openwferu 0.9.10.653 → 0.9.11
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +65 -33
- data/examples/README.txt +4 -0
- data/examples/flowtracing.rb +2 -0
- data/examples/homeworkreview.rb +2 -0
- data/examples/mano_tracker.rb +2 -0
- data/examples/openwferu.rb +3 -1
- data/examples/quotereporter.rb +2 -0
- data/examples/scheduler_cron_usage.rb +3 -1
- data/examples/scheduler_usage.rb +3 -1
- data/lib/openwfe/engine/engine.rb +15 -5
- data/lib/openwfe/expool/expressionpool.rb +30 -4
- data/lib/openwfe/expool/journal.rb +16 -18
- data/lib/openwfe/expool/journal_replay.rb +56 -8
- data/lib/openwfe/expool/wfidgen.rb +17 -8
- data/lib/openwfe/expressions/condition.rb +41 -26
- data/lib/openwfe/expressions/expressionmap.rb +7 -0
- data/lib/openwfe/expressions/fe_cancel.rb +1 -1
- data/lib/openwfe/expressions/fe_concurrence.rb +14 -5
- data/lib/openwfe/expressions/fe_cron.rb +3 -1
- data/lib/openwfe/expressions/fe_cursor.rb +1 -1
- data/lib/openwfe/expressions/fe_fqv.rb +58 -0
- data/lib/openwfe/expressions/fe_if.rb +1 -1
- data/lib/openwfe/expressions/fe_iterator.rb +5 -0
- data/lib/openwfe/expressions/fe_listen.rb +224 -0
- data/lib/openwfe/expressions/fe_misc.rb +32 -9
- data/lib/openwfe/expressions/fe_participant.rb +26 -6
- data/lib/openwfe/expressions/fe_sleep.rb +5 -7
- data/lib/openwfe/expressions/fe_timeout.rb +127 -0
- data/lib/openwfe/expressions/fe_when.rb +13 -1
- data/lib/openwfe/expressions/flowexpression.rb +4 -1
- data/lib/openwfe/expressions/time.rb +10 -27
- data/lib/openwfe/expressions/timeout.rb +23 -6
- data/lib/openwfe/flowexpressionid.rb +7 -6
- data/lib/openwfe/listeners/socketlisteners.rb +1 -1
- data/lib/openwfe/participants/enoparticipants.rb +103 -47
- data/lib/openwfe/participants/participant.rb +29 -3
- data/lib/openwfe/participants/participantmap.rb +10 -2
- data/lib/openwfe/participants/participants.rb +31 -19
- data/lib/openwfe/participants/socketparticipants.rb +3 -1
- data/lib/openwfe/rest/controlclient.rb +5 -18
- data/lib/openwfe/rest/oldrestservlet.rb +279 -0
- data/lib/openwfe/rest/restclient.rb +55 -25
- data/lib/openwfe/rest/worklistclient.rb +35 -44
- data/lib/openwfe/rest/xmlcodec.rb +79 -69
- data/lib/openwfe/rudefinitions.rb +15 -7
- data/lib/openwfe/storage/yamlextras.rb +3 -3
- data/lib/openwfe/util/observable.rb +64 -7
- data/lib/openwfe/util/scheduler.rb +107 -77
- data/lib/openwfe/util/workqueue.rb +5 -11
- data/lib/openwfe/utils.rb +3 -3
- data/lib/openwfe/version.rb +1 -2
- data/lib/openwfe/workitem.rb +3 -4
- data/lib/openwfe/worklist/oldrest.rb +244 -0
- data/lib/openwfe/worklist/storelocks.rb +288 -0
- data/lib/openwfe/worklist/storeparticipant.rb +4 -2
- data/lib/openwfe/worklist/worklist.rb +297 -0
- data/test/cron_test.rb +8 -9
- data/test/eno_test.rb +10 -13
- data/test/flowtestbase.rb +26 -17
- data/test/ft_15_iterator.rb +19 -0
- data/test/ft_23c_wait.rb +2 -2
- data/test/ft_2b_concurrence.rb +2 -2
- data/test/ft_30_socketlistener.rb +5 -1
- data/test/ft_32_journal.rb +1 -1
- data/test/ft_32c_journal.rb +102 -0
- data/test/ft_32d_journal.rb +85 -0
- data/test/ft_45_citerator.rb +25 -0
- data/test/ft_49_condition.rb +60 -2
- data/test/ft_4_misc.rb +15 -0
- data/test/ft_50_xml_attribute.rb +4 -4
- data/test/ft_53_null_noop_participant.rb +66 -0
- data/test/ft_54_listen.rb +223 -0
- data/test/ft_55_ptimeout.rb +64 -0
- data/test/ft_56_timeout.rb +55 -0
- data/test/ft_57_a.rb +109 -0
- data/test/ft_tests.rb +7 -0
- data/test/hparticipant_test.rb +3 -3
- data/test/obs_test.rb +115 -0
- data/test/orest_test.rb +224 -0
- data/test/pending.rb +24 -0
- data/test/rake_qtest.rb +5 -1
- data/test/rake_test.rb +4 -0
- data/test/scheduler_test.rb +31 -2
- data/test/sec_test.rb +7 -3
- data/test/slock_test.rb +82 -0
- metadata +19 -3
- data/test/ft_32b_journal.rb +0 -76
@@ -63,6 +63,8 @@ require 'openwfe/expressions/fe_do'
|
|
63
63
|
require 'openwfe/expressions/fe_save'
|
64
64
|
require 'openwfe/expressions/fe_filter_definition'
|
65
65
|
require 'openwfe/expressions/fe_filter'
|
66
|
+
require 'openwfe/expressions/fe_listen'
|
67
|
+
require 'openwfe/expressions/fe_timeout'
|
66
68
|
|
67
69
|
|
68
70
|
module OpenWFE
|
@@ -122,6 +124,7 @@ module OpenWFE
|
|
122
124
|
register IteratorExpression
|
123
125
|
|
124
126
|
register FqvExpression
|
127
|
+
register AttributeExpression
|
125
128
|
|
126
129
|
register CancelProcessExpression
|
127
130
|
|
@@ -134,6 +137,10 @@ module OpenWFE
|
|
134
137
|
register FilterDefinitionExpression
|
135
138
|
register FilterExpression
|
136
139
|
|
140
|
+
register ListenExpression
|
141
|
+
|
142
|
+
register TimeoutExpression
|
143
|
+
|
137
144
|
register Environment
|
138
145
|
#
|
139
146
|
# only used by get_expression_names()
|
@@ -215,7 +215,7 @@ module OpenWFE
|
|
215
215
|
|
216
216
|
names :concurrent_iterator
|
217
217
|
|
218
|
-
|
218
|
+
attr_accessor :template
|
219
219
|
|
220
220
|
def apply (workitem)
|
221
221
|
|
@@ -224,7 +224,7 @@ module OpenWFE
|
|
224
224
|
return
|
225
225
|
end
|
226
226
|
|
227
|
-
template = @children[0]
|
227
|
+
@template = @children[0]
|
228
228
|
|
229
229
|
@children.clear
|
230
230
|
|
@@ -232,6 +232,11 @@ module OpenWFE
|
|
232
232
|
|
233
233
|
iterator = Iterator.new(self, workitem)
|
234
234
|
|
235
|
+
if not iterator.has_next?
|
236
|
+
reply_to_parent workitem
|
237
|
+
return
|
238
|
+
end
|
239
|
+
|
235
240
|
while iterator.has_next?
|
236
241
|
|
237
242
|
wi = workitem.dup
|
@@ -246,8 +251,11 @@ module OpenWFE
|
|
246
251
|
@children << rawexp.fei
|
247
252
|
end
|
248
253
|
|
249
|
-
|
254
|
+
super
|
255
|
+
end
|
250
256
|
|
257
|
+
def reply_to_parent (workitem)
|
258
|
+
get_expression_pool.remove(@template)
|
251
259
|
super
|
252
260
|
end
|
253
261
|
|
@@ -369,7 +377,7 @@ module OpenWFE
|
|
369
377
|
def do_reply (synchable, workitem)
|
370
378
|
|
371
379
|
synchable.ldebug do
|
372
|
-
"#{self.class}.do_reply() from"+
|
380
|
+
"#{self.class}.do_reply() from " +
|
373
381
|
"#{workitem.last_expression_id.to_debug_s}"
|
374
382
|
end
|
375
383
|
|
@@ -398,7 +406,8 @@ module OpenWFE
|
|
398
406
|
#
|
399
407
|
# over-if
|
400
408
|
|
401
|
-
conditional =
|
409
|
+
conditional =
|
410
|
+
synchable.eval_condition("over-if", workitem, "over-unless")
|
402
411
|
|
403
412
|
if conditional
|
404
413
|
treat_remaining_children(synchable)
|
@@ -168,7 +168,9 @@ module OpenWFE
|
|
168
168
|
@scheduler_job_id = "#{@fei.wfid}__#{@scheduler_job_id}" \
|
169
169
|
if not OpenWFE::starts_with(@name, "//")
|
170
170
|
|
171
|
-
get_scheduler.schedule(
|
171
|
+
get_scheduler.schedule(
|
172
|
+
@tab,
|
173
|
+
{ :schedulable => self, :job_id => @scheduler_job_id })
|
172
174
|
|
173
175
|
ldebug { "reschedule() job id is '#{@scheduler_job_id}'" }
|
174
176
|
|
@@ -39,12 +39,15 @@
|
|
39
39
|
# John Mettraux at openwfe.org
|
40
40
|
#
|
41
41
|
|
42
|
+
require 'openwfe/rest/xmlcodec'
|
42
43
|
require 'openwfe/expressions/flowexpression'
|
43
44
|
|
44
45
|
|
45
46
|
#
|
46
47
|
# 'f', 'q' and 'v' expressions
|
47
48
|
#
|
49
|
+
# 'a' as well
|
50
|
+
#
|
48
51
|
|
49
52
|
module OpenWFE
|
50
53
|
|
@@ -115,5 +118,60 @@ module OpenWFE
|
|
115
118
|
end
|
116
119
|
end
|
117
120
|
|
121
|
+
#
|
122
|
+
# The 'a' or 'attribute' expression. Directly describing some
|
123
|
+
# variable or list content in XML or in YAML.
|
124
|
+
#
|
125
|
+
# _set :field => "list" do
|
126
|
+
# _a """
|
127
|
+
# <list>
|
128
|
+
# <string>a</string>
|
129
|
+
# <string>b</string>
|
130
|
+
# <string>c</string>
|
131
|
+
# </list>
|
132
|
+
# """
|
133
|
+
# end
|
134
|
+
#
|
135
|
+
# or
|
136
|
+
#
|
137
|
+
# _set :field => "list" do
|
138
|
+
# _attribute """
|
139
|
+
# ---
|
140
|
+
# - a
|
141
|
+
# - b
|
142
|
+
# - c
|
143
|
+
# """
|
144
|
+
# end
|
145
|
+
#
|
146
|
+
# Note that it's actually easier to write :
|
147
|
+
#
|
148
|
+
# _set :filed => "list" do
|
149
|
+
# reval "[ 'a', 'b', 'c' ]"
|
150
|
+
# end
|
151
|
+
#
|
152
|
+
# but it's less secure.
|
153
|
+
#
|
154
|
+
class AttributeExpression < FlowExpression
|
155
|
+
|
156
|
+
names :a, :attribute
|
157
|
+
|
158
|
+
def apply workitem
|
159
|
+
|
160
|
+
text = fetch_text_content workitem
|
161
|
+
text = text.strip
|
162
|
+
|
163
|
+
result = if text[0, 3] == "---"
|
164
|
+
YAML.load text
|
165
|
+
else
|
166
|
+
d = REXML::Document.new text
|
167
|
+
XmlCodec::decode_attribute d.root
|
168
|
+
end
|
169
|
+
|
170
|
+
workitem.set_result(result) if result != nil
|
171
|
+
|
172
|
+
reply_to_parent workitem
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
118
176
|
end
|
119
177
|
|
@@ -0,0 +1,224 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2007, John Mettraux, OpenWFE.org
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# . Redistributions of source code must retain the above copyright notice, this
|
10
|
+
# list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# . Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
#
|
16
|
+
# . Neither the name of the "OpenWFE" nor the names of its contributors may be
|
17
|
+
# used to endorse or promote products derived from this software without
|
18
|
+
# specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
#++
|
32
|
+
#
|
33
|
+
# $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
|
34
|
+
#
|
35
|
+
|
36
|
+
#
|
37
|
+
# "made in Japan"
|
38
|
+
#
|
39
|
+
# John Mettraux at openwfe.org
|
40
|
+
#
|
41
|
+
|
42
|
+
require 'openwfe/expressions/timeout'
|
43
|
+
require 'openwfe/expressions/condition'
|
44
|
+
require 'openwfe/expressions/flowexpression'
|
45
|
+
|
46
|
+
|
47
|
+
module OpenWFE
|
48
|
+
|
49
|
+
#
|
50
|
+
# The "listen" expression can be viewed in two ways :
|
51
|
+
#
|
52
|
+
# 1)
|
53
|
+
# It's a hook into the participant map to intercept apply or reply
|
54
|
+
# operations on participants.
|
55
|
+
#
|
56
|
+
# 2)
|
57
|
+
# It allows OpenWFE[ru] to be a bit closer to the 'ideal' process-calculus
|
58
|
+
# world (http://en.wikipedia.org/wiki/Process_calculi)
|
59
|
+
#
|
60
|
+
# Anyway...
|
61
|
+
#
|
62
|
+
# <listen to="alice">
|
63
|
+
# <subprocess ref="notify_bob" />
|
64
|
+
# </listen>
|
65
|
+
#
|
66
|
+
# Whenever a workitem is dispatched (applied) to the participant
|
67
|
+
# named "alice", the subprocess named "notify_bob" is triggered (once).
|
68
|
+
#
|
69
|
+
# listen :to => "^channel_.*", :upon => "reply" do
|
70
|
+
# sequence do
|
71
|
+
# participant :ref => "delta"
|
72
|
+
# participant :ref => "echo"
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# After the listen has been applied, the first workitem coming back from
|
77
|
+
# a participant whose named starts with "channel_" will trigger a sequence
|
78
|
+
# with the participants 'delta' and 'echo'.
|
79
|
+
#
|
80
|
+
# listen :to => "alpha", :where => "${f:color} == red" do
|
81
|
+
# participant :ref => "echo"
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# Will send a copy of the first workitem meant for participant "alpha" to
|
85
|
+
# participant "echo" if this workitem's color field is set to 'red'.
|
86
|
+
#
|
87
|
+
# listen :to => "alpha", :once => "false" do
|
88
|
+
# send_email_to_stakeholders
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# This is some kind of a server : each time a workitem is dispatched to
|
92
|
+
# participant "alpha", the subprocess (or participant) named
|
93
|
+
# 'send_email_to_stakeholders') will receive a copy of that workitem.
|
94
|
+
# Use with care.
|
95
|
+
#
|
96
|
+
# listen :to => "alpha", :once => "false", :timeout => "1M2w" do
|
97
|
+
# send_email_to_stakeholders
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# The 'listen' expression understands the 'timeout' attribute. It can thus
|
101
|
+
# be instructed to stop listening after a certain amount of time (here,
|
102
|
+
# after one month and two weeks).
|
103
|
+
#
|
104
|
+
class ListenExpression < FlowExpression
|
105
|
+
include TimeoutMixin, ConditionMixin
|
106
|
+
|
107
|
+
names :listen
|
108
|
+
|
109
|
+
attr_accessor \
|
110
|
+
:participant_regex,
|
111
|
+
:once,
|
112
|
+
:upon,
|
113
|
+
:call_count
|
114
|
+
|
115
|
+
def apply (workitem)
|
116
|
+
|
117
|
+
if @children.size < 1
|
118
|
+
reply_to_parent workitem
|
119
|
+
return
|
120
|
+
end
|
121
|
+
|
122
|
+
@participant_regex = lookup_attribute :to, workitem
|
123
|
+
|
124
|
+
raise "attribute 'to' is missing for expression 'listen'" \
|
125
|
+
unless @participant_regex
|
126
|
+
|
127
|
+
@once = lookup_boolean_attribute :once, workitem, true
|
128
|
+
|
129
|
+
ldebug { "apply() @once is #{@once}" }
|
130
|
+
|
131
|
+
@upon = lookup_attribute(:upon, workitem, "apply")[0, 5].downcase
|
132
|
+
@upon = if @upon == "reply"
|
133
|
+
:reply
|
134
|
+
else
|
135
|
+
:apply
|
136
|
+
end
|
137
|
+
|
138
|
+
@call_count = 0
|
139
|
+
|
140
|
+
determine_timeout()
|
141
|
+
reschedule(get_scheduler)
|
142
|
+
|
143
|
+
store_itself
|
144
|
+
end
|
145
|
+
|
146
|
+
def cancel
|
147
|
+
stop_observing
|
148
|
+
end
|
149
|
+
|
150
|
+
def reply_to_parent (workitem)
|
151
|
+
stop_observing
|
152
|
+
super
|
153
|
+
end
|
154
|
+
|
155
|
+
#
|
156
|
+
# Only called in case of timeout.
|
157
|
+
#
|
158
|
+
def trigger (params)
|
159
|
+
reply_to_parent workitem
|
160
|
+
end
|
161
|
+
|
162
|
+
#
|
163
|
+
# This is the method called when a 'listenable' workitem comes in
|
164
|
+
#
|
165
|
+
def call (channel, *args)
|
166
|
+
synchronize do
|
167
|
+
|
168
|
+
upon = args[0]
|
169
|
+
|
170
|
+
return if upon != @upon
|
171
|
+
|
172
|
+
workitem = args[1].dup
|
173
|
+
|
174
|
+
conditional = eval_condition(:where, workitem)
|
175
|
+
#
|
176
|
+
# note that the values if the incoming workitem (not the
|
177
|
+
# workitem at apply time) are used for the evaluation
|
178
|
+
# of the condition (if necessary).
|
179
|
+
|
180
|
+
return if conditional == false
|
181
|
+
|
182
|
+
return if @once and @call_count > 0
|
183
|
+
|
184
|
+
ldebug { "call() through for #{workitem.fei.to_s}" }
|
185
|
+
|
186
|
+
@call_count += 1
|
187
|
+
store_itself()
|
188
|
+
|
189
|
+
#ldebug { "call() @call_count is #{@call_count}" }
|
190
|
+
|
191
|
+
parent = if @once
|
192
|
+
self
|
193
|
+
else
|
194
|
+
nil
|
195
|
+
end
|
196
|
+
|
197
|
+
get_expression_pool.launch_template(
|
198
|
+
parent, @call_count - 1, @children[0], workitem, nil)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
#
|
203
|
+
# Registers for timeout and start observing the participant
|
204
|
+
# activity.
|
205
|
+
#
|
206
|
+
def reschedule (scheduler)
|
207
|
+
|
208
|
+
to_reschedule(scheduler)
|
209
|
+
start_observing
|
210
|
+
end
|
211
|
+
|
212
|
+
protected
|
213
|
+
|
214
|
+
def start_observing
|
215
|
+
get_participant_map.add_observer @participant_regex, self
|
216
|
+
end
|
217
|
+
|
218
|
+
def stop_observing
|
219
|
+
get_participant_map.remove_observer self
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
|
@@ -87,6 +87,32 @@ module OpenWFE
|
|
87
87
|
# (<tt>engine.application_context[:ruby_eval_allowed] = true</tt>), this
|
88
88
|
# expression will throw an exception at apply.
|
89
89
|
#
|
90
|
+
# some examples :
|
91
|
+
#
|
92
|
+
# <reval>
|
93
|
+
# workitem.customer_name = "doug"
|
94
|
+
# # or for short
|
95
|
+
# wi.customer_address = "midtown 21_21 design"
|
96
|
+
# </reval>
|
97
|
+
#
|
98
|
+
# in a Ruby process definition :
|
99
|
+
#
|
100
|
+
# sequence do
|
101
|
+
# _set :field => "customer" do
|
102
|
+
# reval """
|
103
|
+
# {
|
104
|
+
# :name => "Cheezburger",
|
105
|
+
# :age => 34,
|
106
|
+
# :comment => "I can haz ?",
|
107
|
+
# :timestamp => Time.now.to_s
|
108
|
+
# }
|
109
|
+
# """
|
110
|
+
# end
|
111
|
+
# end
|
112
|
+
#
|
113
|
+
# Don't embed too much Ruby into your process definitions, it might
|
114
|
+
# hurt...
|
115
|
+
#
|
90
116
|
class RevalExpression < FlowExpression
|
91
117
|
|
92
118
|
names :reval
|
@@ -99,12 +125,8 @@ module OpenWFE
|
|
99
125
|
|
100
126
|
def apply (workitem)
|
101
127
|
|
102
|
-
|
103
|
-
|
104
|
-
#reply_to_parent(workitem)
|
105
|
-
#return
|
106
|
-
raise "evaluation of ruby code is not allowed"
|
107
|
-
end
|
128
|
+
raise "evaluation of ruby code is not allowed" \
|
129
|
+
if @application_context[:ruby_eval_allowed] != true
|
108
130
|
|
109
131
|
escape = lookup_boolean_attribute('escape', workitem, false)
|
110
132
|
|
@@ -115,13 +137,14 @@ module OpenWFE
|
|
115
137
|
|
116
138
|
code = code.to_s
|
117
139
|
|
118
|
-
|
119
|
-
|
140
|
+
wi = workitem
|
141
|
+
|
142
|
+
result = OpenWFE::eval_safely code, SAFETY_LEVEL, binding()
|
120
143
|
|
121
144
|
workitem.set_result(result) \
|
122
145
|
if result != nil # 'false' is a valid result
|
123
146
|
|
124
|
-
reply_to_parent
|
147
|
+
reply_to_parent workitem
|
125
148
|
end
|
126
149
|
end
|
127
150
|
|
@@ -82,7 +82,7 @@ module OpenWFE
|
|
82
82
|
# The Participant expressions includes the FilterMixin and thus
|
83
83
|
# understands and applies the "filter" attribute.
|
84
84
|
#
|
85
|
-
# Since
|
85
|
+
# Since OpenWFEru 0.9.9, the attributes of the participant expression are
|
86
86
|
# set inside a hash field named 'params' just available to the participant.
|
87
87
|
# Thus in
|
88
88
|
#
|
@@ -95,6 +95,17 @@ module OpenWFE
|
|
95
95
|
# When the workitem gets back from the participant, the field 'params' is
|
96
96
|
# deleted.
|
97
97
|
#
|
98
|
+
# The participant expressions include the TimeoutMixin, it means that
|
99
|
+
# a timeout can be stated :
|
100
|
+
#
|
101
|
+
# <participant ref="toto" timeout="2w1d" />
|
102
|
+
#
|
103
|
+
# If after 2 weeks and 1 day (15 days), participant "toto" hasn't replied,
|
104
|
+
# the workitem will get cancelled and the flow will resume (behind the
|
105
|
+
# scene, participant "toto", will receive a CancelItem instance bearing
|
106
|
+
# the same FlowExpressionId as the initial workitem and the participant
|
107
|
+
# implementation is responsible for the cancel application).
|
108
|
+
#
|
98
109
|
class ParticipantExpression < FlowExpression
|
99
110
|
include FilterMixin
|
100
111
|
include TimeoutMixin
|
@@ -105,7 +116,6 @@ module OpenWFE
|
|
105
116
|
:participant_name,
|
106
117
|
:applied_workitem
|
107
118
|
|
108
|
-
|
109
119
|
def apply (workitem)
|
110
120
|
|
111
121
|
remove_timedout_flag workitem
|
@@ -117,8 +127,7 @@ module OpenWFE
|
|
117
127
|
@participant_name = fetch_text_content workitem \
|
118
128
|
unless @participant_name
|
119
129
|
|
120
|
-
|
121
|
-
reschedule(get_scheduler)
|
130
|
+
schedule_timeout()
|
122
131
|
|
123
132
|
filter_in workitem
|
124
133
|
|
@@ -127,10 +136,19 @@ module OpenWFE
|
|
127
136
|
workitem.params = lookup_attributes workitem
|
128
137
|
|
129
138
|
get_participant_map.dispatch @participant_name, workitem
|
139
|
+
get_participant_map.onotify @participant_name, :apply, workitem
|
140
|
+
#
|
141
|
+
# these two pmap calls were combined, but with the :reply
|
142
|
+
# notification in reply_to_parent() it feels more
|
143
|
+
# elegant like that
|
130
144
|
end
|
131
145
|
|
132
146
|
def reply_to_parent (workitem)
|
133
147
|
|
148
|
+
get_participant_map.onotify @participant_name, :reply, workitem
|
149
|
+
#
|
150
|
+
# for 'listen' expressions waiting for replies
|
151
|
+
|
134
152
|
unschedule_timeout()
|
135
153
|
|
136
154
|
workitem.attributes.delete "params"
|
@@ -147,6 +165,8 @@ module OpenWFE
|
|
147
165
|
#
|
148
166
|
def cancel
|
149
167
|
|
168
|
+
unschedule_timeout()
|
169
|
+
|
150
170
|
wi = super()
|
151
171
|
|
152
172
|
return wi unless @applied_workitem
|
@@ -157,7 +177,7 @@ module OpenWFE
|
|
157
177
|
cancelitem = OpenWFE::CancelItem.new(@applied_workitem)
|
158
178
|
get_participant_map.dispatch(@participant_name, cancelitem)
|
159
179
|
|
160
|
-
|
180
|
+
nil
|
161
181
|
end
|
162
182
|
|
163
183
|
#
|
@@ -170,7 +190,7 @@ module OpenWFE
|
|
170
190
|
|
171
191
|
begin
|
172
192
|
|
173
|
-
|
193
|
+
#@scheduler_job_id = nil
|
174
194
|
#
|
175
195
|
# so that cancel won't unschedule without need
|
176
196
|
|
@@ -137,13 +137,11 @@ module OpenWFE
|
|
137
137
|
"(#{OpenWFE::to_iso8601_date(@awakening_time)})"
|
138
138
|
end
|
139
139
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
@scheduler_job_id =
|
146
|
-
scheduler.schedule_at(@awakening_time, self, nil)
|
140
|
+
@scheduler_job_id = "sleep_#{self.fei.to_s}"
|
141
|
+
|
142
|
+
scheduler.schedule_at(
|
143
|
+
@awakening_time,
|
144
|
+
{ :schedulable => self, :job_id => @scheduler_job_id })
|
147
145
|
|
148
146
|
ldebug do
|
149
147
|
"[re]schedule() @scheduler_job_id is '#{@scheduler_job_id}' "+
|