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.
Files changed (87) hide show
  1. data/README.txt +65 -33
  2. data/examples/README.txt +4 -0
  3. data/examples/flowtracing.rb +2 -0
  4. data/examples/homeworkreview.rb +2 -0
  5. data/examples/mano_tracker.rb +2 -0
  6. data/examples/openwferu.rb +3 -1
  7. data/examples/quotereporter.rb +2 -0
  8. data/examples/scheduler_cron_usage.rb +3 -1
  9. data/examples/scheduler_usage.rb +3 -1
  10. data/lib/openwfe/engine/engine.rb +15 -5
  11. data/lib/openwfe/expool/expressionpool.rb +30 -4
  12. data/lib/openwfe/expool/journal.rb +16 -18
  13. data/lib/openwfe/expool/journal_replay.rb +56 -8
  14. data/lib/openwfe/expool/wfidgen.rb +17 -8
  15. data/lib/openwfe/expressions/condition.rb +41 -26
  16. data/lib/openwfe/expressions/expressionmap.rb +7 -0
  17. data/lib/openwfe/expressions/fe_cancel.rb +1 -1
  18. data/lib/openwfe/expressions/fe_concurrence.rb +14 -5
  19. data/lib/openwfe/expressions/fe_cron.rb +3 -1
  20. data/lib/openwfe/expressions/fe_cursor.rb +1 -1
  21. data/lib/openwfe/expressions/fe_fqv.rb +58 -0
  22. data/lib/openwfe/expressions/fe_if.rb +1 -1
  23. data/lib/openwfe/expressions/fe_iterator.rb +5 -0
  24. data/lib/openwfe/expressions/fe_listen.rb +224 -0
  25. data/lib/openwfe/expressions/fe_misc.rb +32 -9
  26. data/lib/openwfe/expressions/fe_participant.rb +26 -6
  27. data/lib/openwfe/expressions/fe_sleep.rb +5 -7
  28. data/lib/openwfe/expressions/fe_timeout.rb +127 -0
  29. data/lib/openwfe/expressions/fe_when.rb +13 -1
  30. data/lib/openwfe/expressions/flowexpression.rb +4 -1
  31. data/lib/openwfe/expressions/time.rb +10 -27
  32. data/lib/openwfe/expressions/timeout.rb +23 -6
  33. data/lib/openwfe/flowexpressionid.rb +7 -6
  34. data/lib/openwfe/listeners/socketlisteners.rb +1 -1
  35. data/lib/openwfe/participants/enoparticipants.rb +103 -47
  36. data/lib/openwfe/participants/participant.rb +29 -3
  37. data/lib/openwfe/participants/participantmap.rb +10 -2
  38. data/lib/openwfe/participants/participants.rb +31 -19
  39. data/lib/openwfe/participants/socketparticipants.rb +3 -1
  40. data/lib/openwfe/rest/controlclient.rb +5 -18
  41. data/lib/openwfe/rest/oldrestservlet.rb +279 -0
  42. data/lib/openwfe/rest/restclient.rb +55 -25
  43. data/lib/openwfe/rest/worklistclient.rb +35 -44
  44. data/lib/openwfe/rest/xmlcodec.rb +79 -69
  45. data/lib/openwfe/rudefinitions.rb +15 -7
  46. data/lib/openwfe/storage/yamlextras.rb +3 -3
  47. data/lib/openwfe/util/observable.rb +64 -7
  48. data/lib/openwfe/util/scheduler.rb +107 -77
  49. data/lib/openwfe/util/workqueue.rb +5 -11
  50. data/lib/openwfe/utils.rb +3 -3
  51. data/lib/openwfe/version.rb +1 -2
  52. data/lib/openwfe/workitem.rb +3 -4
  53. data/lib/openwfe/worklist/oldrest.rb +244 -0
  54. data/lib/openwfe/worklist/storelocks.rb +288 -0
  55. data/lib/openwfe/worklist/storeparticipant.rb +4 -2
  56. data/lib/openwfe/worklist/worklist.rb +297 -0
  57. data/test/cron_test.rb +8 -9
  58. data/test/eno_test.rb +10 -13
  59. data/test/flowtestbase.rb +26 -17
  60. data/test/ft_15_iterator.rb +19 -0
  61. data/test/ft_23c_wait.rb +2 -2
  62. data/test/ft_2b_concurrence.rb +2 -2
  63. data/test/ft_30_socketlistener.rb +5 -1
  64. data/test/ft_32_journal.rb +1 -1
  65. data/test/ft_32c_journal.rb +102 -0
  66. data/test/ft_32d_journal.rb +85 -0
  67. data/test/ft_45_citerator.rb +25 -0
  68. data/test/ft_49_condition.rb +60 -2
  69. data/test/ft_4_misc.rb +15 -0
  70. data/test/ft_50_xml_attribute.rb +4 -4
  71. data/test/ft_53_null_noop_participant.rb +66 -0
  72. data/test/ft_54_listen.rb +223 -0
  73. data/test/ft_55_ptimeout.rb +64 -0
  74. data/test/ft_56_timeout.rb +55 -0
  75. data/test/ft_57_a.rb +109 -0
  76. data/test/ft_tests.rb +7 -0
  77. data/test/hparticipant_test.rb +3 -3
  78. data/test/obs_test.rb +115 -0
  79. data/test/orest_test.rb +224 -0
  80. data/test/pending.rb +24 -0
  81. data/test/rake_qtest.rb +5 -1
  82. data/test/rake_test.rb +4 -0
  83. data/test/scheduler_test.rb +31 -2
  84. data/test/sec_test.rb +7 -3
  85. data/test/slock_test.rb +82 -0
  86. metadata +19 -3
  87. 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()
@@ -85,7 +85,7 @@ module OpenWFE
85
85
 
86
86
  def apply (workitem)
87
87
 
88
- conditional = eval_condition(:if, workitem)
88
+ conditional = eval_condition(:if, workitem, :unless)
89
89
  #
90
90
  # for example : <cancel-process if="${approved} == false"/>
91
91
 
@@ -215,7 +215,7 @@ module OpenWFE
215
215
 
216
216
  names :concurrent_iterator
217
217
 
218
- #attr_accessor :iterator
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
- get_expression_pool.remove(template)
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 = synchable.eval_condition("over-if", workitem)
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(@tab, @scheduler_job_id, self, nil)
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
 
@@ -335,7 +335,7 @@ module OpenWFE
335
335
 
336
336
  def apply (workitem)
337
337
 
338
- conditional = eval_condition(:if, workitem)
338
+ conditional = eval_condition(:if, workitem, :unless)
339
339
  #
340
340
  # for example : <break if="${approved} == true"/>
341
341
 
@@ -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
 
@@ -100,7 +100,7 @@ module OpenWFE
100
100
 
101
101
  workitem.unset_result
102
102
 
103
- test = eval_condition(:test, workitem)
103
+ test = eval_condition(:test, workitem, :not)
104
104
 
105
105
  if @children.length < 1
106
106
  workitem.set_result test if test
@@ -77,6 +77,11 @@ module OpenWFE
77
77
 
78
78
  @iterator = Iterator.new(self, workitem)
79
79
 
80
+ if not @iterator.has_next?
81
+ reply_to_parent workitem
82
+ return
83
+ end
84
+
80
85
  reply workitem
81
86
  end
82
87
 
@@ -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
- if @application_context[:ruby_eval_allowed] != true
103
- #lwarn { "apply() :ruby_eval_allowed not set to true" }
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
- #result = eval(code)
119
- result = OpenWFE::eval_safely(code, SAFETY_LEVEL, binding())
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(workitem)
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 OpenWFE 0.9.9, the attributes of the participant expression are
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
- determine_timeout()
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
- return nil
180
+ nil
161
181
  end
162
182
 
163
183
  #
@@ -170,7 +190,7 @@ module OpenWFE
170
190
 
171
191
  begin
172
192
 
173
- @scheduler_job_id = nil
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
- if already_scheduled?
141
- ldebug { "[re]schedule() already scheduled" }
142
- return
143
- end
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}' "+