openwferu 0.9.4 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/mano_tracker.rb +13 -6
- data/examples/quotereporter.rb +3 -2
- data/lib/openwfe/engine/engine.rb +31 -4
- data/lib/openwfe/engine/file_persisted_engine.rb +35 -9
- data/lib/openwfe/expool/expressionpool.rb +116 -67
- data/lib/openwfe/expool/expstorage.rb +142 -101
- data/lib/openwfe/expool/history.rb +7 -2
- data/lib/openwfe/expool/yamlexpstorage.rb +150 -6
- data/lib/openwfe/expressions/{fe_condition.rb → condition.rb} +4 -6
- data/lib/openwfe/expressions/expressionmap.rb +8 -0
- data/lib/openwfe/expressions/fe_cancel.rb +109 -0
- data/lib/openwfe/expressions/fe_concurrence.rb +252 -16
- data/lib/openwfe/expressions/fe_cursor.rb +8 -3
- data/lib/openwfe/{util/stoppable.rb → expressions/fe_do.rb} +42 -11
- data/lib/openwfe/expressions/fe_iterator.rb +4 -3
- data/lib/openwfe/expressions/fe_misc.rb +3 -2
- data/lib/openwfe/expressions/fe_participant.rb +5 -0
- data/lib/openwfe/expressions/fe_raw.rb +10 -2
- data/lib/openwfe/expressions/fe_subprocess.rb +1 -1
- data/lib/openwfe/expressions/fe_time.rb +43 -23
- data/lib/openwfe/expressions/fe_value.rb +1 -1
- data/lib/openwfe/expressions/flowexpression.rb +22 -22
- data/lib/openwfe/expressions/raw_prog.rb +20 -39
- data/lib/openwfe/expressions/raw_xml.rb +6 -6
- data/lib/openwfe/expressions/timeout.rb +8 -3
- data/lib/openwfe/expressions/wtemplate.rb +67 -0
- data/lib/openwfe/flowexpressionid.rb +4 -1
- data/lib/openwfe/participants/atomparticipants.rb +13 -1
- data/lib/openwfe/participants/enoparticipant.rb +66 -5
- data/lib/openwfe/participants/participantmap.rb +12 -0
- data/lib/openwfe/rudefinitions.rb +15 -3
- data/lib/openwfe/service.rb +4 -5
- data/lib/openwfe/storage/yamlfilestorage.rb +72 -45
- data/lib/openwfe/util/dollar.rb +17 -4
- data/lib/openwfe/util/lru.rb +154 -0
- data/lib/openwfe/util/otime.rb +26 -5
- data/lib/openwfe/util/scheduler.rb +44 -36
- data/lib/openwfe/util/schedulers.rb +4 -2
- data/lib/openwfe/utils.rb +62 -0
- data/lib/openwfe/version.rb +1 -1
- data/lib/openwfe/worklist/storeparticipant.rb +34 -5
- data/test/eno_test.rb +69 -0
- data/test/file_persistence_test.rb +13 -11
- data/test/flowtestbase.rb +29 -15
- data/test/ft_0.rb +2 -1
- data/test/ft_0b_sequence.rb +2 -1
- data/test/ft_0c_testname.rb +6 -5
- data/test/ft_0d_participant.rb +2 -1
- data/test/ft_10_loop.rb +11 -6
- data/test/ft_10b_loop2.rb +63 -0
- data/test/ft_11_ppd.rb +39 -13
- data/test/ft_12_blockparticipant.rb +2 -1
- data/test/ft_13_eno.rb +3 -2
- data/test/ft_14_subprocess.rb +2 -1
- data/test/ft_14b_subprocess.rb +2 -1
- data/test/ft_15_iterator.rb +2 -1
- data/test/ft_16_fqv.rb +2 -1
- data/test/ft_17_condition.rb +2 -1
- data/test/ft_18_pname.rb +2 -1
- data/test/ft_19_csv.rb +2 -1
- data/test/ft_1_unset.rb +14 -18
- data/test/ft_1b_unset.rb +39 -0
- data/test/ft_20_cron.rb +2 -1
- data/test/ft_21_cron.rb +2 -1
- data/test/ft_22_history.rb +7 -5
- data/test/ft_23_when.rb +2 -1
- data/test/ft_23b_when.rb +2 -1
- data/test/ft_24_def.rb +2 -1
- data/test/ft_25_cancel.rb +79 -0
- data/test/ft_26_load.rb +197 -0
- data/test/ft_2_concurrence.rb +89 -15
- data/test/ft_2b_concurrence.rb +152 -0
- data/test/ft_2c_concurrence.rb +39 -0
- data/test/ft_3_equals.rb +4 -3
- data/test/ft_4_misc.rb +4 -3
- data/test/ft_5_time.rb +2 -1
- data/test/ft_6_lambda.rb +2 -1
- data/test/ft_7_lose.rb +53 -17
- data/test/ft_8_forget.rb +7 -6
- data/test/ft_9_cursor.rb +8 -7
- data/test/hparticipant_test.rb +37 -14
- data/test/lru_test.rb +79 -0
- data/test/misc_test.rb +16 -0
- data/test/rake_qtest.rb +7 -0
- data/test/raw_prog_test.rb +0 -13
- data/test/rutest_utils.rb +15 -2
- data/test/scheduler_test.rb +31 -4
- data/test/timeout_test.rb +6 -2
- data/test/wfid_test.rb +68 -0
- metadata +169 -158
- data/lib/openwfe/expool/journalexpstorage.rb +0 -312
- data/lib/openwfe/util/lru_cache.rb +0 -149
@@ -41,6 +41,7 @@
|
|
41
41
|
|
42
42
|
require 'openwfe/utils'
|
43
43
|
require 'openwfe/rudefinitions'
|
44
|
+
require 'openwfe/expressions/condition'
|
44
45
|
require 'openwfe/expressions/flowexpression'
|
45
46
|
|
46
47
|
|
@@ -50,7 +51,84 @@ require 'openwfe/expressions/flowexpression'
|
|
50
51
|
|
51
52
|
module OpenWFE
|
52
53
|
|
54
|
+
#
|
55
|
+
# The concurrence expression will execute each of its (direct) children
|
56
|
+
# in parallel threads.
|
57
|
+
#
|
58
|
+
# Thus,
|
59
|
+
#
|
60
|
+
# <concurrence>
|
61
|
+
# <participant ref="pa" />
|
62
|
+
# <participant ref="pb" />
|
63
|
+
# </concurrence>
|
64
|
+
#
|
65
|
+
# Participants pa and pb will be 'treated' in parallel (quasi
|
66
|
+
# simultaneously).
|
67
|
+
#
|
68
|
+
# The concurrence expressions accept many attributes, that can get
|
69
|
+
# combined. By default, the concurrence waits for all its children to
|
70
|
+
# reply and returns the workitem of the first child that replied.
|
71
|
+
# The attributes tune this behaviour.
|
72
|
+
#
|
73
|
+
# <em>count</em>
|
74
|
+
#
|
75
|
+
# <concurrence count="1">
|
76
|
+
# <participant ref="pa" />
|
77
|
+
# <participant ref="pb" />
|
78
|
+
# </concurrence>
|
79
|
+
#
|
80
|
+
# The concurrence will be over as soon as 'pa' or 'pb' replied, i.e.
|
81
|
+
# as soon as "1" child replied.
|
82
|
+
#
|
83
|
+
# <em>remaining</em>
|
84
|
+
#
|
85
|
+
# The attribute 'remaining' can take two values 'cancel' (the default) and
|
86
|
+
# 'forget'.
|
87
|
+
# Cancelled children are completely wiped away, forgotten ones continue
|
88
|
+
# to operate but their reply will simply get discarded.
|
89
|
+
#
|
90
|
+
# <em>over-if</em>
|
91
|
+
#
|
92
|
+
# 'over-if' accepts a 'boolean expression' (something replying 'true' or
|
93
|
+
# 'false'), if the expression evaluates to true, the concurrence will be
|
94
|
+
# over and the remaining children will get cancelled (the default) or
|
95
|
+
# forgotten.
|
96
|
+
#
|
97
|
+
# <em>merge</em>
|
98
|
+
#
|
99
|
+
# By default, the first child to reply to its parent 'concurrence'
|
100
|
+
# expression 'wins', i.e. its workitem is used for resuming the flow (after
|
101
|
+
# the concurrence).
|
102
|
+
#
|
103
|
+
# [first] The default : the first child to reply wins
|
104
|
+
# [last] The last child to reply wins
|
105
|
+
# [highest] The first 'defined' child (in the list of children) will win
|
106
|
+
# [lowest] The last 'defined' child (in the list of children) will win
|
107
|
+
#
|
108
|
+
# Thus, in that example
|
109
|
+
#
|
110
|
+
# <concurrence merge="lowest">
|
111
|
+
# <participant ref="pa" />
|
112
|
+
# <participant ref="pb" />
|
113
|
+
# </concurrence>
|
114
|
+
#
|
115
|
+
# when the concurrence is done, the workitem of 'pb' is used to resume the
|
116
|
+
# flow after the concurrence.
|
117
|
+
#
|
118
|
+
# <em>merge-type</em>
|
119
|
+
#
|
120
|
+
# [override] The default : no mix of values between the workitems do occur
|
121
|
+
# [mix] Priority is given to the 'winning' workitem but their values
|
122
|
+
# get mixed
|
123
|
+
#
|
124
|
+
# The merge occurs are the top level of workitem attributes.
|
125
|
+
#
|
126
|
+
# More complex merge behaviour can be obtained by extending the
|
127
|
+
# GenericSyncExpression class. But the default sync options are already
|
128
|
+
# numerous and powerful.
|
129
|
+
#
|
53
130
|
class ConcurrenceExpression < SequenceExpression
|
131
|
+
include ConditionMixin
|
54
132
|
|
55
133
|
attr_accessor \
|
56
134
|
:sync_expression
|
@@ -73,6 +151,7 @@ module OpenWFE
|
|
73
151
|
@children.each do |child|
|
74
152
|
Thread.new do
|
75
153
|
begin
|
154
|
+
#ldebug { "apply() child : #{child.to_debug_s}" }
|
76
155
|
concurrence.synchronize do
|
77
156
|
get_expression_pool().apply(child, workitem.dup)
|
78
157
|
end
|
@@ -141,6 +220,11 @@ module OpenWFE
|
|
141
220
|
@count = determine_count(synchable, workitem)
|
142
221
|
@cancel_remaining = cancel_remaining?(synchable, workitem)
|
143
222
|
|
223
|
+
merge = synchable.lookup_attribute(:merge, workitem, :first)
|
224
|
+
merge_type = synchable.lookup_attribute(:merge_type, workitem, :mix)
|
225
|
+
|
226
|
+
@merge_array = MergeArray.new(merge, merge_type)
|
227
|
+
|
144
228
|
@unready_queue = []
|
145
229
|
end
|
146
230
|
|
@@ -162,7 +246,11 @@ module OpenWFE
|
|
162
246
|
synchable.store_itself()
|
163
247
|
|
164
248
|
queue.each do |workitem|
|
165
|
-
do_reply(synchable, workitem)
|
249
|
+
break if do_reply(synchable, workitem)
|
250
|
+
#
|
251
|
+
# do_reply() will return 'true' as soon as the
|
252
|
+
# concurrence is over, if this is the case, the
|
253
|
+
# queue should not be treated anymore
|
166
254
|
end
|
167
255
|
end
|
168
256
|
end
|
@@ -200,27 +288,52 @@ module OpenWFE
|
|
200
288
|
"#{workitem.last_expression_id.to_debug_s}"
|
201
289
|
end
|
202
290
|
|
291
|
+
@merge_array.push(synchable, workitem)
|
292
|
+
|
203
293
|
@reply_count = @reply_count + 1
|
204
294
|
|
205
295
|
@remaining_children.delete(workitem.last_expression_id)
|
206
296
|
|
207
297
|
if @remaining_children.length <= 0
|
208
|
-
|
209
|
-
return
|
298
|
+
reply_to_parent(synchable)
|
299
|
+
return true
|
210
300
|
end
|
211
301
|
|
212
302
|
if @count > 0 and @reply_count >= @count
|
213
303
|
treat_remaining_children(synchable)
|
214
|
-
|
215
|
-
return
|
304
|
+
reply_to_parent(synchable)
|
305
|
+
return true
|
306
|
+
end
|
307
|
+
|
308
|
+
#
|
309
|
+
# over-if
|
310
|
+
|
311
|
+
conditional = synchable.eval_condition("over-if", workitem)
|
312
|
+
|
313
|
+
if conditional
|
314
|
+
treat_remaining_children(synchable)
|
315
|
+
reply_to_parent(synchable)
|
316
|
+
return true
|
216
317
|
end
|
217
318
|
|
319
|
+
#
|
320
|
+
# not over, resuming
|
321
|
+
|
218
322
|
synchable.store_itself()
|
219
323
|
|
220
324
|
#synchable.ldebug do
|
221
325
|
# "#{self.class}.do_reply() not replying to parent "+
|
222
326
|
# "#{workitem.last_expression_id.to_debug_s}"
|
223
327
|
#end
|
328
|
+
|
329
|
+
return false
|
330
|
+
end
|
331
|
+
|
332
|
+
def reply_to_parent (synchable)
|
333
|
+
|
334
|
+
workitem = @merge_array.do_merge
|
335
|
+
|
336
|
+
synchable.reply_to_parent(workitem)
|
224
337
|
end
|
225
338
|
|
226
339
|
def treat_remaining_children (synchable)
|
@@ -260,20 +373,143 @@ module OpenWFE
|
|
260
373
|
return -1 if i < 1
|
261
374
|
return i
|
262
375
|
end
|
263
|
-
end
|
264
376
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
377
|
+
#
|
378
|
+
# This inner class is used to gather workitems before the final
|
379
|
+
# merge, which is triggered by calling the do_merge() method
|
380
|
+
# which returns the merged workitem.
|
381
|
+
#
|
382
|
+
class MergeArray
|
271
383
|
|
272
|
-
|
384
|
+
attr_accessor \
|
385
|
+
:workitem,
|
386
|
+
:workitems_by_arrival,
|
387
|
+
:workitems_by_altitude,
|
388
|
+
:merge,
|
389
|
+
:merge_type
|
390
|
+
|
391
|
+
def initialize (merge, merge_type)
|
392
|
+
|
393
|
+
@merge = merge.downcase
|
394
|
+
@merge_type = merge_type.downcase
|
395
|
+
|
396
|
+
ensure_merge_settings()
|
397
|
+
|
398
|
+
@workitem = nil
|
399
|
+
|
400
|
+
if highest? or lowest?
|
401
|
+
@workitems_by_arrival = []
|
402
|
+
@workitems_by_altitude = []
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
def push (synchable, wi)
|
407
|
+
|
408
|
+
if not @workitems_by_arrival
|
409
|
+
#
|
410
|
+
# last or first
|
411
|
+
#
|
412
|
+
source, target = if first?
|
413
|
+
[ @workitem, wi ]
|
414
|
+
else
|
415
|
+
[ wi, @workitem ]
|
416
|
+
end
|
417
|
+
@workitem = merge(target, source)
|
418
|
+
|
419
|
+
return
|
420
|
+
end
|
421
|
+
|
422
|
+
index = synchable.children.index(
|
423
|
+
wi.last_expression_id)
|
424
|
+
|
425
|
+
@workitems_by_arrival << wi
|
426
|
+
@workitems_by_altitude[index] = wi
|
427
|
+
end
|
428
|
+
|
429
|
+
#
|
430
|
+
# merges the workitems stored here
|
431
|
+
#
|
432
|
+
def do_merge
|
433
|
+
|
434
|
+
return @workitem if @workitem
|
435
|
+
|
436
|
+
list = if first?
|
437
|
+
@workitems_by_arrival.reverse
|
438
|
+
elsif last?
|
439
|
+
@workitems_by_arrival
|
440
|
+
elsif highest?
|
441
|
+
@workitems_by_altitude.reverse
|
442
|
+
elsif lowest?
|
443
|
+
@workitems_by_altitude
|
444
|
+
end
|
445
|
+
|
446
|
+
result = nil
|
447
|
+
|
448
|
+
list.each do |wi|
|
449
|
+
next unless wi
|
450
|
+
result = merge(result, wi)
|
451
|
+
end
|
452
|
+
|
453
|
+
#puts "___ result :"
|
454
|
+
#puts result.to_s
|
455
|
+
#puts
|
456
|
+
|
457
|
+
return result
|
458
|
+
end
|
459
|
+
|
460
|
+
protected
|
461
|
+
|
462
|
+
def first?
|
463
|
+
@merge == "first"
|
464
|
+
end
|
465
|
+
def last?
|
466
|
+
@merge == "last"
|
467
|
+
end
|
468
|
+
def highest?
|
469
|
+
@merge == "highest"
|
470
|
+
end
|
471
|
+
def lowest?
|
472
|
+
@merge == "lowest"
|
473
|
+
end
|
474
|
+
|
475
|
+
def mix?
|
476
|
+
@merge_type == "mix"
|
477
|
+
end
|
478
|
+
def override?
|
479
|
+
@merge_type == "override"
|
480
|
+
end
|
481
|
+
|
482
|
+
#
|
483
|
+
# Making sure @merge and @merge_type are set to
|
484
|
+
# appropriate values.
|
485
|
+
#
|
486
|
+
def ensure_merge_settings
|
487
|
+
|
488
|
+
@merge_type = "mix" unless override?
|
489
|
+
@merge = "first" unless last? or highest? or lowest?
|
490
|
+
end
|
491
|
+
|
492
|
+
def merge (wiTarget, wiSource)
|
493
|
+
|
494
|
+
return wiSource unless wiTarget
|
495
|
+
return wiTarget unless wiSource
|
496
|
+
|
497
|
+
return wiSource if override?
|
498
|
+
|
499
|
+
wiSource.attributes.each do | k, v |
|
500
|
+
|
501
|
+
#puts "merge() '#{k}' => '#{v}'"
|
502
|
+
|
503
|
+
nk = OpenWFE::fulldup(k)
|
504
|
+
nv = OpenWFE::fulldup(v)
|
505
|
+
|
506
|
+
wiTarget.attributes[nk] = nv
|
507
|
+
end
|
508
|
+
|
509
|
+
return wiTarget
|
510
|
+
end
|
511
|
+
end
|
273
512
|
|
274
|
-
wiSource.attributes.each do | k, v |
|
275
|
-
wiTarget.attributes[k.dup] = v.dup
|
276
|
-
end
|
277
513
|
end
|
278
514
|
|
279
515
|
end
|
@@ -39,8 +39,9 @@
|
|
39
39
|
# John Mettraux at openwfe.org
|
40
40
|
#
|
41
41
|
|
42
|
+
require 'openwfe/expressions/condition'
|
43
|
+
require 'openwfe/expressions/wtemplate'
|
42
44
|
require 'openwfe/expressions/flowexpression'
|
43
|
-
require 'openwfe/expressions/fe_condition'
|
44
45
|
|
45
46
|
|
46
47
|
#
|
@@ -69,6 +70,7 @@ module OpenWFE
|
|
69
70
|
class CursorExpression < WithTemplateExpression
|
70
71
|
|
71
72
|
attr_accessor \
|
73
|
+
:loop_id,
|
72
74
|
:current_child_id,
|
73
75
|
:current_child_fei
|
74
76
|
|
@@ -77,6 +79,8 @@ module OpenWFE
|
|
77
79
|
|
78
80
|
def apply (workitem)
|
79
81
|
|
82
|
+
@loop_id = 0
|
83
|
+
|
80
84
|
@current_child_id = -1
|
81
85
|
|
82
86
|
clean_children_list()
|
@@ -119,6 +123,7 @@ module OpenWFE
|
|
119
123
|
reply_to_parent(workitem)
|
120
124
|
return
|
121
125
|
end
|
126
|
+
@loop_id += 1
|
122
127
|
@current_child_id = 0
|
123
128
|
end
|
124
129
|
end
|
@@ -134,8 +139,8 @@ module OpenWFE
|
|
134
139
|
#
|
135
140
|
# launch the next child as a template
|
136
141
|
|
137
|
-
get_expression_pool
|
138
|
-
|
142
|
+
get_expression_pool.launch_template(
|
143
|
+
self, @loop_id, @current_child_fei, workitem, nil)
|
139
144
|
end
|
140
145
|
|
141
146
|
#
|
@@ -39,30 +39,61 @@
|
|
39
39
|
# John Mettraux at openwfe.org
|
40
40
|
#
|
41
41
|
|
42
|
+
require 'openwfe/expressions/flowexpression'
|
43
|
+
|
44
|
+
|
45
|
+
#
|
46
|
+
# do / redo / undo
|
47
|
+
#
|
42
48
|
|
43
49
|
module OpenWFE
|
44
50
|
|
45
51
|
#
|
46
|
-
#
|
47
|
-
# methods around it to a class (or an object).
|
52
|
+
# in preparation.
|
48
53
|
#
|
49
|
-
|
54
|
+
class DoExpression < FlowExpression
|
55
|
+
|
56
|
+
attr_accessor \
|
57
|
+
:name
|
50
58
|
|
51
|
-
|
52
|
-
|
59
|
+
#
|
60
|
+
# apply / reply
|
61
|
+
|
62
|
+
def apply (workitem)
|
53
63
|
end
|
54
64
|
|
55
|
-
def
|
56
|
-
@stopped = true
|
65
|
+
def reply (workitem)
|
57
66
|
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# in preparation.
|
71
|
+
#
|
72
|
+
class UndoExpression < FlowExpression
|
73
|
+
|
74
|
+
#
|
75
|
+
# apply / reply
|
58
76
|
|
59
|
-
def
|
60
|
-
@stopped = false
|
77
|
+
def apply (workitem)
|
61
78
|
end
|
62
79
|
|
63
|
-
def
|
64
|
-
|
80
|
+
#def reply (workitem)
|
81
|
+
#end
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# in preparation.
|
86
|
+
#
|
87
|
+
class RedoExpression < FlowExpression
|
88
|
+
|
89
|
+
#
|
90
|
+
# apply / reply
|
91
|
+
|
92
|
+
def apply (workitem)
|
65
93
|
end
|
94
|
+
|
95
|
+
#def reply (workitem)
|
96
|
+
#end
|
66
97
|
end
|
67
98
|
|
68
99
|
end
|
@@ -64,7 +64,8 @@ module OpenWFE
|
|
64
64
|
#
|
65
65
|
class IteratorExpression < WithTemplateExpression
|
66
66
|
|
67
|
-
attr_accessor
|
67
|
+
attr_accessor \
|
68
|
+
:iterator
|
68
69
|
|
69
70
|
def apply (workitem)
|
70
71
|
|
@@ -89,8 +90,8 @@ module OpenWFE
|
|
89
90
|
|
90
91
|
store_itself()
|
91
92
|
|
92
|
-
get_expression_pool
|
93
|
-
|
93
|
+
get_expression_pool.launch_template(
|
94
|
+
self, 0, @children[0], workitem, nil)
|
94
95
|
end
|
95
96
|
end
|
96
97
|
|
@@ -88,11 +88,12 @@ module OpenWFE
|
|
88
88
|
code = OpenWFE::lookup_vf_attribute(self, workitem, 'code')
|
89
89
|
|
90
90
|
code = OpenWFE::fetch_text_content(self, workitem, escape) \
|
91
|
-
|
91
|
+
unless code
|
92
92
|
|
93
93
|
result = eval(code.to_s)
|
94
94
|
|
95
|
-
OpenWFE::set_result(workitem, result)
|
95
|
+
OpenWFE::set_result(workitem, result) \
|
96
|
+
if result != nil # 'false' is a valid result
|
96
97
|
|
97
98
|
reply_to_parent(workitem)
|
98
99
|
end
|
@@ -69,6 +69,8 @@ module OpenWFE
|
|
69
69
|
|
70
70
|
def apply (workitem)
|
71
71
|
|
72
|
+
remove_timedout_flag(workitem)
|
73
|
+
|
72
74
|
@applied_workitem = workitem.dup
|
73
75
|
|
74
76
|
@participant_name = OpenWFE::lookup_ref(self, workitem)
|
@@ -122,6 +124,9 @@ module OpenWFE
|
|
122
124
|
# so that cancel won't unschedule without need
|
123
125
|
|
124
126
|
cancel()
|
127
|
+
|
128
|
+
set_timedout_flag(@applied_workitem)
|
129
|
+
|
125
130
|
reply_to_parent(@applied_workitem)
|
126
131
|
rescue
|
127
132
|
lerror do
|
@@ -107,8 +107,15 @@ module OpenWFE
|
|
107
107
|
#
|
108
108
|
# is it a subprocess ?
|
109
109
|
|
110
|
-
template
|
111
|
-
|
110
|
+
if (not template) and (not exp_class)
|
111
|
+
|
112
|
+
template = get_participant_map.lookup_participant(exp_name)
|
113
|
+
|
114
|
+
unless template
|
115
|
+
exp_name = OpenWFE::to_underscore(exp_name)
|
116
|
+
template = get_participant_map.lookup_participant(exp_name)
|
117
|
+
end
|
118
|
+
end
|
112
119
|
#
|
113
120
|
# is it a directly a participant ?
|
114
121
|
|
@@ -167,6 +174,7 @@ module OpenWFE
|
|
167
174
|
|
168
175
|
get_expression_pool().launch_template(
|
169
176
|
self,
|
177
|
+
0,
|
170
178
|
template,
|
171
179
|
workitem,
|
172
180
|
lookup_attributes(workitem))
|
@@ -44,7 +44,7 @@ require 'openwfe/utils'
|
|
44
44
|
require 'openwfe/util/otime'
|
45
45
|
require 'openwfe/util/scheduler'
|
46
46
|
require 'openwfe/expressions/timeout'
|
47
|
-
require 'openwfe/expressions/
|
47
|
+
require 'openwfe/expressions/condition'
|
48
48
|
|
49
49
|
|
50
50
|
#
|
@@ -108,31 +108,31 @@ module OpenWFE
|
|
108
108
|
:awakening_time
|
109
109
|
|
110
110
|
def apply (workitem)
|
111
|
-
synchronize do
|
111
|
+
#synchronize do
|
112
112
|
|
113
|
-
|
114
|
-
|
113
|
+
sfor = lookup_attribute(:for, workitem)
|
114
|
+
suntil = lookup_attribute(:until, workitem)
|
115
115
|
|
116
|
-
|
116
|
+
tuntil = nil
|
117
117
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
118
|
+
if suntil
|
119
|
+
tuntil = suntil
|
120
|
+
elsif sfor
|
121
|
+
tfor = OpenWFE::parse_time_string(sfor)
|
122
|
+
ldebug { "apply() tfor is '#{tfor}'" }
|
123
|
+
tuntil = Time.new.to_f + tfor
|
124
|
+
end
|
125
125
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
126
|
+
if not tuntil
|
127
|
+
reply_to_parent(workitem)
|
128
|
+
return
|
129
|
+
end
|
130
130
|
|
131
|
-
|
132
|
-
|
131
|
+
@awakening_time = tuntil
|
132
|
+
@applied_workitem = workitem.dup
|
133
133
|
|
134
|
-
|
135
|
-
end
|
134
|
+
reschedule(get_scheduler)
|
135
|
+
#end
|
136
136
|
end
|
137
137
|
|
138
138
|
#def reply (workitem)
|
@@ -159,6 +159,8 @@ module OpenWFE
|
|
159
159
|
#
|
160
160
|
def reschedule (scheduler)
|
161
161
|
|
162
|
+
return unless @awakening_time
|
163
|
+
|
162
164
|
ldebug do
|
163
165
|
"[re]schedule() " +
|
164
166
|
"will sleep until '#{@awakening_time}' " +
|
@@ -197,10 +199,12 @@ module OpenWFE
|
|
197
199
|
class CronExpression < TimeExpression
|
198
200
|
|
199
201
|
attr_accessor \
|
200
|
-
:raw_child, :tab, :name
|
202
|
+
:raw_child, :tab, :name, :counter
|
201
203
|
|
202
204
|
def apply (workitem)
|
203
205
|
|
206
|
+
@counter = 0
|
207
|
+
|
204
208
|
if @children.size < 1
|
205
209
|
reply_to_parent(workitem)
|
206
210
|
return
|
@@ -229,7 +233,7 @@ module OpenWFE
|
|
229
233
|
# (have to do it after the reschedule, so that the schedule
|
230
234
|
# info is stored within the variable)
|
231
235
|
|
232
|
-
set_variable(@name, self)
|
236
|
+
set_variable(@name, self) if @name
|
233
237
|
|
234
238
|
#
|
235
239
|
# resume flow
|
@@ -260,8 +264,17 @@ module OpenWFE
|
|
260
264
|
@raw_child.application_context = @application_context
|
261
265
|
|
262
266
|
begin
|
267
|
+
|
263
268
|
get_expression_pool.launch_template(
|
264
|
-
@fei.wfid, @raw_child, @applied_workitem.dup)
|
269
|
+
@fei.wfid, @counter, @raw_child, @applied_workitem.dup)
|
270
|
+
|
271
|
+
#
|
272
|
+
# update count and store self
|
273
|
+
|
274
|
+
@counter += 1
|
275
|
+
|
276
|
+
set_variable(@name, self) if @name
|
277
|
+
|
265
278
|
rescue
|
266
279
|
lerror do
|
267
280
|
"trigger() cron caught exception\n"+
|
@@ -277,6 +290,8 @@ module OpenWFE
|
|
277
290
|
#
|
278
291
|
def reschedule (scheduler)
|
279
292
|
|
293
|
+
#return unless @applied_workitem
|
294
|
+
|
280
295
|
@scheduler_job_id = @name.dup
|
281
296
|
|
282
297
|
@scheduler_job_id = "#{@fei.wfid}__#{@scheduler_job_id}" \
|
@@ -314,6 +329,8 @@ module OpenWFE
|
|
314
329
|
|
315
330
|
def apply (workitem)
|
316
331
|
|
332
|
+
remove_timedout_flag(workitem)
|
333
|
+
|
317
334
|
if @children.size < 1
|
318
335
|
reply_to_parent(workitem)
|
319
336
|
return
|
@@ -366,6 +383,7 @@ module OpenWFE
|
|
366
383
|
#
|
367
384
|
# do timeout...
|
368
385
|
#
|
386
|
+
set_timedout_flag(@applied_workitem)
|
369
387
|
reply_to_parent(@applied_workitem)
|
370
388
|
return
|
371
389
|
end
|
@@ -377,6 +395,8 @@ module OpenWFE
|
|
377
395
|
|
378
396
|
def reschedule (scheduler)
|
379
397
|
|
398
|
+
#return unless @applied_workitem
|
399
|
+
|
380
400
|
@scheduler_job_id =
|
381
401
|
scheduler.schedule_in(@frequency, self, nil)
|
382
402
|
|