openwferu 0.9.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. data/examples/mano_tracker.rb +165 -0
  2. data/examples/scheduler_cron_usage.rb +46 -0
  3. data/examples/scheduler_usage.rb +54 -0
  4. data/lib/openwfe/contextual.rb +7 -1
  5. data/lib/openwfe/engine/engine.rb +58 -15
  6. data/lib/openwfe/expool/expressionpool.rb +116 -14
  7. data/lib/openwfe/expool/expstorage.rb +12 -12
  8. data/lib/openwfe/expool/journalexpstorage.rb +1 -1
  9. data/lib/openwfe/expool/yamlexpstorage.rb +58 -22
  10. data/lib/openwfe/expressions/environment.rb +32 -2
  11. data/lib/openwfe/expressions/expressionmap.rb +17 -0
  12. data/lib/openwfe/expressions/fe_condition.rb +122 -0
  13. data/lib/openwfe/expressions/fe_cursor.rb +14 -5
  14. data/lib/openwfe/expressions/fe_participant.rb +55 -4
  15. data/lib/openwfe/expressions/fe_raw.rb +43 -12
  16. data/lib/openwfe/expressions/fe_subprocess.rb +10 -0
  17. data/lib/openwfe/expressions/fe_time.rb +117 -22
  18. data/lib/openwfe/expressions/fe_value.rb +27 -8
  19. data/lib/openwfe/expressions/flowexpression.rb +13 -6
  20. data/lib/openwfe/expressions/raw_prog.rb +13 -11
  21. data/lib/openwfe/expressions/timeout.rb +94 -0
  22. data/lib/openwfe/flowexpressionid.rb +17 -19
  23. data/lib/openwfe/logging.rb +35 -16
  24. data/lib/openwfe/participants/atomparticipants.rb +31 -7
  25. data/lib/openwfe/participants/enoparticipant.rb +43 -3
  26. data/lib/openwfe/participants/participant.rb +21 -1
  27. data/lib/openwfe/participants/participantmap.rb +4 -2
  28. data/lib/openwfe/participants/participants.rb +12 -17
  29. data/lib/openwfe/participants/soapparticipants.rb +15 -3
  30. data/lib/openwfe/rudefinitions.rb +3 -0
  31. data/lib/openwfe/service.rb +8 -0
  32. data/lib/openwfe/storage/yamlfilestorage.rb +85 -47
  33. data/lib/openwfe/{otime.rb → util/otime.rb} +0 -0
  34. data/lib/openwfe/util/scheduler.rb +415 -231
  35. data/lib/openwfe/util/schedulers.rb +11 -3
  36. data/lib/openwfe/util/stoppable.rb +69 -0
  37. data/lib/openwfe/utils.rb +14 -25
  38. data/lib/openwfe/workitem.rb +12 -6
  39. data/lib/openwfe/worklist/storeparticipant.rb +145 -0
  40. data/test/{atomtest.rb → atom_test.rb} +0 -0
  41. data/test/{crontest.rb → cron_test.rb} +7 -6
  42. data/test/cronline_test.rb +51 -0
  43. data/test/{dollartest.rb → dollar_test.rb} +0 -0
  44. data/test/{feitest.rb → fei_test.rb} +0 -0
  45. data/test/file_persistence_test.rb +15 -9
  46. data/test/flowtestbase.rb +11 -5
  47. data/test/ft_0.rb +8 -0
  48. data/test/ft_10_loop.rb +72 -10
  49. data/test/ft_11_ppd.rb +49 -0
  50. data/test/ft_17_condition.rb +83 -0
  51. data/test/ft_18_pname.rb +59 -0
  52. data/test/hparticipant_test.rb +96 -0
  53. data/test/{misctest.rb → misc_test.rb} +1 -1
  54. data/test/rake_qtest.rb +10 -4
  55. data/test/rake_test.rb +12 -1
  56. data/test/raw_prog_test.rb +1 -1
  57. data/test/restart_cron_test.rb +78 -0
  58. data/test/restart_test.rb +79 -0
  59. data/test/scheduler_test.rb +92 -0
  60. data/test/{timetest.rb → time_test.rb} +3 -38
  61. data/test/timeout_test.rb +73 -0
  62. metadata +26 -11
  63. data/lib/openwfe/worklist/worklists.rb +0 -175
@@ -68,17 +68,21 @@ module OpenWFE
68
68
  new_environment() if not @environment_id
69
69
  end
70
70
 
71
- def instantiate_real_expression (workitem)
71
+ def instantiate_real_expression \
72
+ (workitem, exp_class=nil, attributes=nil)
72
73
 
73
- attributes = extract_attributes()
74
+ exp_class = expression_class() unless exp_class
74
75
 
75
- eclass = expression_class()
76
+ raise "unknown expression '#{expression_name}'" \
77
+ unless exp_class
76
78
 
77
- raise "unknown expression '#{expression_name}'" if not eclass
79
+ #ldebug do
80
+ # "instantiate_real_expression() exp_class is #{exp_class}"
81
+ #end
78
82
 
79
- ldebug { "instantiate_real_expression() eclass is #{eclass}" }
83
+ attributes = extract_attributes() unless attributes
80
84
 
81
- expression = eclass.new(
85
+ expression = exp_class.new(
82
86
  @fei,
83
87
  @parent_id,
84
88
  @environment_id,
@@ -94,14 +98,41 @@ module OpenWFE
94
98
 
95
99
  def apply (workitem)
96
100
 
97
- template = lookup_variable(expression_name())
101
+ exp_name = expression_name()
102
+
103
+ exp_class = nil
104
+ attributes = nil
105
+
106
+ template = lookup_variable(exp_name)
107
+ #
108
+ # is it a subprocess ?
109
+
110
+ template = get_participant_map.lookup_participant(exp_name) \
111
+ unless template
112
+ #
113
+ # is it a directly a participant ?
114
+
115
+ if template
98
116
 
99
- if template and template.kind_of? OpenWFE::FlowExpressionId
100
- launch_template(template, workitem)
101
- else
102
- expression = instantiate_real_expression(workitem)
103
- expression.apply(workitem)
117
+ if template.kind_of? OpenWFE::FlowExpressionId
118
+ launch_template(template, workitem)
119
+ return
120
+ end
121
+
122
+ if template.kind_of? OpenWFE::Participant
123
+ exp_class = OpenWFE::ParticipantExpression
124
+ attributes = extract_attributes()
125
+ attributes["ref"] = exp_name
126
+ end
104
127
  end
128
+
129
+ #
130
+ # the classical case...
131
+
132
+ expression = instantiate_real_expression(
133
+ workitem, exp_class, attributes)
134
+
135
+ expression.apply(workitem)
105
136
  end
106
137
 
107
138
  #def reply (workitem)
@@ -78,6 +78,8 @@ module OpenWFE
78
78
 
79
79
  template_fei = lookup_variable(ref)
80
80
 
81
+ #template_fei = lookup_participant(ref) if not template_fei
82
+
81
83
  raise "did not find any subprocess named '#{ref}'" \
82
84
  if not template_fei
83
85
 
@@ -96,6 +98,14 @@ module OpenWFE
96
98
 
97
99
  #def reply (workitem)
98
100
  #end
101
+
102
+ #protected
103
+ # def lookup_participant (ref)
104
+ # participant = get_participant_map.lookup_participant(ref)
105
+ # return nil unless participant
106
+ # #
107
+ # # builds a participant expression on the fly
108
+ # end
99
109
  end
100
110
 
101
111
  end
@@ -39,8 +39,9 @@
39
39
  # John Mettraux at openwfe.org
40
40
  #
41
41
 
42
- require 'openwfe/otime'
43
42
  require 'openwfe/rudefinitions'
43
+ require 'openwfe/utils'
44
+ require 'openwfe/util/otime'
44
45
  require 'openwfe/util/scheduler'
45
46
 
46
47
 
@@ -57,14 +58,12 @@ module OpenWFE
57
58
  # localization for <sleep/> and <cron/>.
58
59
  #
59
60
  class TimeExpression < FlowExpression
61
+ include Schedulable
60
62
 
61
63
  attr_accessor \
64
+ :applied_workitem,
62
65
  :scheduler_job_id
63
66
 
64
- def get_scheduler
65
- return @application_context[S_SCHEDULER]
66
- end
67
-
68
67
  #
69
68
  # Makes sure to cancel any scheduler job associated with this
70
69
  # expression
@@ -95,10 +94,8 @@ module OpenWFE
95
94
  # to participant 'alpha'.
96
95
  #
97
96
  class SleepExpression < TimeExpression
98
- include Schedulable
99
97
 
100
98
  attr_accessor \
101
- :sleeping_workitem,
102
99
  :awakening_time
103
100
 
104
101
  def apply (workitem)
@@ -123,19 +120,9 @@ module OpenWFE
123
120
  end
124
121
 
125
122
  @awakening_time = tuntil
126
- @sleeping_workitem = workitem.dup
127
-
128
- ldebug do
129
- "apply() " +
130
- "will sleep until '#{tuntil}' " +
131
- "(#{OpenWFE::to_iso8601_date(tuntil)})"
132
- end
133
-
134
- @scheduler_job_id = get_scheduler.schedule_at(tuntil, self, nil)
123
+ @applied_workitem = workitem.dup
135
124
 
136
- ldebug { "apply() @scheduler_job_id is #{@scheduler_job_id}" }
137
-
138
- store_itself()
125
+ reschedule(get_scheduler)
139
126
  end
140
127
  end
141
128
 
@@ -149,16 +136,124 @@ module OpenWFE
149
136
  #
150
137
  def trigger (params)
151
138
  ldebug do
152
- "trigger() #{@fei.to_debug_s} waking up (#{Time.new.to_f})"
139
+ "trigger() #{@fei.to_debug_s} waking up (#{Time.new.to_f}) "+
140
+ "(scheduler #{get_scheduler.object_id})"
153
141
  end
154
- reply_to_parent(@sleeping_workitem)
142
+ reply_to_parent(@applied_workitem)
143
+ end
144
+
145
+ #
146
+ # [Re]schedules this expression, effectively registering it within
147
+ # the scheduler.
148
+ # This method is called when the expression is applied and each
149
+ # time the owning engine restarts.
150
+ #
151
+ def reschedule (scheduler)
152
+
153
+ ldebug do
154
+ "[re]schedule() " +
155
+ "will sleep until '#{@awakening_time}' " +
156
+ "(#{OpenWFE::to_iso8601_date(@awakening_time)})"
157
+ end
158
+
159
+ @scheduler_job_id =
160
+ scheduler.schedule_at(@awakening_time, self, nil)
161
+
162
+ ldebug do
163
+ "[re]schedule() @scheduler_job_id is #{@scheduler_job_id} "+
164
+ " (scheduler #{scheduler.object_id})"
165
+ end
166
+
167
+ store_itself()
155
168
  end
156
169
  end
157
170
 
158
171
  #
159
- # TODO #6929 : implement me
172
+ # <cron tab="0 9-17 * * mon-fri" name="//reminder">
173
+ # <send-reminder/>
174
+ # </cron>
160
175
  #
161
176
  class CronExpression < TimeExpression
177
+
178
+ attr_accessor \
179
+ :raw_child, :tab, :name
180
+
181
+ def apply (workitem)
182
+
183
+ if @children.size < 1
184
+ reply_to_parent(workitem)
185
+ return
186
+ end
187
+
188
+ @applied_workitem = workitem.dup
189
+ @applied_workitem.flow_expression_id = nil
190
+
191
+ @tab = lookup_attribute(:tab, workitem)
192
+ @name = lookup_attribute(:name, workitem)
193
+
194
+ @raw_child, _fei = get_expression_pool.fetch(@children[0])
195
+ @raw_child.parent_id = nil
196
+
197
+ clean_children()
198
+
199
+ @children = nil
200
+
201
+ #
202
+ # schedule self
203
+
204
+ reschedule(get_scheduler)
205
+
206
+ #
207
+ # store self as a variable
208
+ # (have to do it after the reschedule, so that the schedule
209
+ # info is stored within the variable)
210
+
211
+ set_variable(@name, self)
212
+
213
+ #
214
+ # resume flow
215
+
216
+ reply_to_parent(workitem)
217
+ end
218
+
219
+ def reply (workitem)
220
+ # discard silently... should never get called though
221
+ end
222
+
223
+ #def cancel ()
224
+ #end
225
+ #
226
+ # implemented in parent TimeExpression class
227
+
228
+ def trigger (params)
229
+ #
230
+ # launch raw child
231
+
232
+ ldebug { "trigger() cron : #{@fei.to_debug_s}" }
233
+
234
+ @raw_child.application_context = @application_context
235
+
236
+ begin
237
+ get_expression_pool.launch_template(
238
+ @fei.wfid, @raw_child, @applied_workitem.dup)
239
+ rescue
240
+ lerror do
241
+ "trigger() cron caught exception\n"+
242
+ OpenWFE::exception_to_s($!)
243
+ end
244
+ end
245
+ end
246
+
247
+ def reschedule (scheduler)
248
+
249
+ @scheduler_id = get_scheduler.schedule(@tab, @name, self, nil)
250
+
251
+ ldebug { "reschedule() job id is #{@scheduler_id}" }
252
+
253
+ #store_itself()
254
+ #
255
+ # done by the containing environment itself
256
+ end
162
257
  end
163
258
 
164
259
  end
@@ -43,6 +43,7 @@ require 'openwfe/workitem'
43
43
  require 'openwfe/flowexpressionid'
44
44
  require 'openwfe/expressions/flowexpression'
45
45
  require 'openwfe/expressions/fe_utils'
46
+ require 'openwfe/expressions/fe_condition'
46
47
 
47
48
 
48
49
  #
@@ -187,6 +188,7 @@ module OpenWFE
187
188
  # <if/>
188
189
  #
189
190
  class IfExpression < FlowExpression
191
+ include ConditionMixin
190
192
 
191
193
  attr_accessor \
192
194
  :condition_replied
@@ -195,11 +197,19 @@ module OpenWFE
195
197
 
196
198
  reply_to_parent(workitem) if @children.length < 1
197
199
 
198
- @condition_replied = false
200
+ test = eval_condition(:test, workitem)
201
+
202
+ @condition_replied = (test != nil)
203
+ #
204
+ # if the "test" attribute is not used, test will be null
199
205
 
200
206
  store_itself()
201
207
 
202
- get_expression_pool.apply(@children[0], workitem)
208
+ if test != nil
209
+ apply_consequence(test, workitem, 0)
210
+ else
211
+ get_expression_pool.apply(@children[0], workitem)
212
+ end
203
213
  end
204
214
 
205
215
  def reply (workitem)
@@ -215,11 +225,7 @@ module OpenWFE
215
225
 
216
226
  store_itself()
217
227
 
218
- if result
219
- apply_consequence(1, workitem)
220
- else
221
- apply_consequence(2, workitem)
222
- end
228
+ apply_consequence(result, workitem)
223
229
  end
224
230
 
225
231
  def reply_to_parent(workitem)
@@ -229,7 +235,20 @@ module OpenWFE
229
235
 
230
236
  protected
231
237
 
232
- def apply_consequence (index, workitem)
238
+ def apply_consequence (index, workitem, offset=1)
239
+
240
+ if index == true
241
+ index = 0
242
+ elsif index == false
243
+ index = 1
244
+ elsif index == nil
245
+ index = 1
246
+ elsif not index.integer?
247
+ index = 0
248
+ end
249
+
250
+ index = index + offset
251
+
233
252
  if index >= @children.length
234
253
  reply_to_parent(workitem)
235
254
  else
@@ -346,19 +346,24 @@ module OpenWFE
346
346
  end
347
347
 
348
348
  #
349
- # takes care of removing all the children
349
+ # Takes care of removing all the children of this expression, if any.
350
350
  #
351
351
  def clean_children
352
- @children.each do |children_fei|
353
- get_expression_pool.remove(children_fei)
352
+
353
+ return unless @children
354
+
355
+ @children.each do |child_fei|
356
+ get_expression_pool.remove(child_fei) \
357
+ if child_fei.kind_of? FlowExpressionId
354
358
  end
355
359
  end
356
360
 
357
361
  #
358
- # currently only used by dollar.rb and its ${r:some_ruby_code},
359
- # returns the binding in this flow expression
362
+ # Currently only used by dollar.rb and its ${r:some_ruby_code},
363
+ # returns the binding in this flow expression.
360
364
  #
361
365
  def get_binding
366
+
362
367
  return binding()
363
368
  end
364
369
 
@@ -369,15 +374,17 @@ module OpenWFE
369
374
  # just included the MonitorMixin. No hassle.
370
375
  #
371
376
  def synchronize
377
+
372
378
  get_expression_pool.get_monitor(@fei).synchronize do
373
379
  yield
374
380
  end
375
381
  end
376
382
 
377
383
  #
378
- # some eye candy
384
+ # Some eye candy
379
385
  #
380
386
  def to_s
387
+
381
388
  s = "* #{@fei.to_debug_s}"
382
389
 
383
390
  if @parent_id
@@ -125,11 +125,11 @@ module OpenWFE
125
125
  ind = tab * indentation
126
126
 
127
127
  s << ind
128
- s << OpenWFE.make_safe(@name)
128
+ s << OpenWFE::make_safe(@name)
129
129
 
130
130
  sa = ""
131
131
  @attributes.each do |k, v|
132
- sa << ", :#{k} => '#{v}'"
132
+ sa << ", :#{OpenWFE::to_underscore(k)} => '#{v}'"
133
133
  end
134
134
  s << sa[1..-1] if sa.length > 0
135
135
 
@@ -225,14 +225,16 @@ module OpenWFE
225
225
  methodname = m.to_s
226
226
 
227
227
  expname = OpenWFE.to_expression_name(methodname)
228
- if not @exp_names.include? expname
229
- #raise "No expression named '#{methodname}' (#{expname}) found"
230
- #raise "No expression named '#{expname}' found"
231
- params = args[0]
232
- params = {} if not params
233
- params["ref"] = methodname
234
- return make_expression("subprocess", params, &block)
235
- end
228
+
229
+ #if not @exp_names.include? expname
230
+ # #raise "No expression named '#{methodname}' (#{expname}) found"
231
+ # #raise "No expression named '#{expname}' found"
232
+ # params = args[0]
233
+ # params = {} if not params
234
+ # params["ref"] = methodname
235
+ # return make_expression("subprocess", params, &block)
236
+ #end
237
+
236
238
  make_expression(expname, args[0], &block)
237
239
  end
238
240
 
@@ -367,7 +369,7 @@ module OpenWFE
367
369
  # with 'do' and 'redo' that are.
368
370
  #
369
371
  KEYWORDS = [
370
- :if, :do, :redo, :undo, :print
372
+ :if, :do, :redo, :undo, :print, :sleep, :loop, :break
371
373
  ]
372
374
 
373
375
  #