openwferu 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/examples/engine_template.rb +182 -0
  2. data/examples/openwferu.rb +6 -7
  3. data/lib/openwfe/contextual.rb +8 -6
  4. data/lib/openwfe/engine/engine.rb +49 -14
  5. data/lib/openwfe/expool/expressionpool.rb +48 -17
  6. data/lib/openwfe/expool/history.rb +64 -14
  7. data/lib/openwfe/expool/journal.rb +66 -28
  8. data/lib/openwfe/expool/journal_replay.rb +190 -48
  9. data/lib/openwfe/expool/wfidgen.rb +51 -6
  10. data/lib/openwfe/expressions/condition.rb +49 -5
  11. data/lib/openwfe/expressions/environment.rb +9 -37
  12. data/lib/openwfe/expressions/expressionmap.rb +15 -1
  13. data/lib/openwfe/expressions/fe_concurrence.rb +4 -4
  14. data/lib/openwfe/expressions/fe_cron.rb +1 -5
  15. data/lib/openwfe/expressions/fe_do.rb +96 -26
  16. data/lib/openwfe/expressions/fe_equals.rb +190 -0
  17. data/lib/openwfe/expressions/fe_fqv.rb +25 -7
  18. data/lib/openwfe/expressions/fe_if.rb +262 -0
  19. data/lib/openwfe/expressions/fe_iterator.rb +3 -4
  20. data/lib/openwfe/expressions/fe_losfor.rb +0 -1
  21. data/lib/openwfe/expressions/fe_misc.rb +4 -5
  22. data/lib/openwfe/expressions/fe_participant.rb +2 -3
  23. data/lib/openwfe/expressions/fe_raw.rb +71 -31
  24. data/lib/openwfe/expressions/fe_reserve.rb +141 -0
  25. data/lib/openwfe/expressions/fe_sequence.rb +0 -1
  26. data/lib/openwfe/expressions/fe_sleep.rb +3 -58
  27. data/lib/openwfe/expressions/fe_subprocess.rb +6 -5
  28. data/lib/openwfe/expressions/fe_value.rb +20 -121
  29. data/lib/openwfe/expressions/fe_wait.rb +79 -0
  30. data/lib/openwfe/expressions/fe_when.rb +31 -96
  31. data/lib/openwfe/expressions/flowexpression.rb +112 -19
  32. data/lib/openwfe/expressions/raw_prog.rb +8 -116
  33. data/lib/openwfe/expressions/simplerep.rb +197 -0
  34. data/lib/openwfe/expressions/time.rb +266 -0
  35. data/lib/openwfe/expressions/timeout.rb +2 -2
  36. data/lib/openwfe/flowexpressionid.rb +22 -0
  37. data/lib/openwfe/listeners/socketlisteners.rb +15 -1
  38. data/lib/openwfe/participants/participantmap.rb +12 -1
  39. data/lib/openwfe/participants/participants.rb +7 -1
  40. data/lib/openwfe/rudefinitions.rb +1 -6
  41. data/lib/openwfe/service.rb +8 -0
  42. data/lib/openwfe/util/irb.rb +86 -0
  43. data/lib/openwfe/util/ometa.rb +3 -3
  44. data/lib/openwfe/util/safe.rb +26 -34
  45. data/lib/openwfe/util/scheduler.rb +133 -76
  46. data/lib/openwfe/utils.rb +1 -1
  47. data/lib/openwfe/version.rb +2 -2
  48. data/lib/openwfe/workitem.rb +38 -0
  49. data/lib/openwfe/worklist/storeparticipant.rb +27 -2
  50. data/test/console_test.rb +15 -0
  51. data/test/flowtestbase.rb +20 -28
  52. data/test/ft_12_blockparticipant.rb +24 -0
  53. data/test/ft_14b_subprocess.rb +18 -0
  54. data/test/ft_22_history.rb +22 -1
  55. data/test/ft_23_when.rb +29 -2
  56. data/test/ft_23b_when.rb +17 -0
  57. data/test/ft_23c_wait.rb +87 -0
  58. data/test/ft_2_concurrence.rb +15 -14
  59. data/test/ft_2b_concurrence.rb +4 -4
  60. data/test/ft_32_journal.rb +29 -6
  61. data/test/ft_32b_journal.rb +76 -0
  62. data/test/ft_36_subprocids.rb +96 -0
  63. data/test/ft_37_pnames.rb +55 -0
  64. data/test/ft_38_tag.rb +128 -0
  65. data/test/ft_39_reserve.rb +119 -0
  66. data/test/ft_3_equals.rb +20 -1
  67. data/test/ft_40_defined.rb +72 -0
  68. data/test/ft_41_case.rb +124 -0
  69. data/test/ft_4_misc.rb +17 -0
  70. data/test/ft_5_time.rb +15 -20
  71. data/test/ft_7_lose.rb +2 -3
  72. data/test/ft_8_forget.rb +1 -1
  73. data/test/ft_tests.rb +9 -0
  74. data/test/hparticipant_test.rb +47 -1
  75. data/test/nut_0_irb.rb +20 -0
  76. data/test/raw_prog_test.rb +6 -0
  77. data/test/safely_test.rb +31 -41
  78. data/test/wfid_test.rb +43 -0
  79. metadata +21 -4
  80. data/lib/openwfe/expressions/fe_utils.rb +0 -151
@@ -41,6 +41,7 @@
41
41
 
42
42
  require 'openwfe/util/otime'
43
43
  require 'openwfe/util/scheduler'
44
+ require 'openwfe/expressions/time'
44
45
 
45
46
 
46
47
  #
@@ -49,61 +50,6 @@ require 'openwfe/util/scheduler'
49
50
 
50
51
  module OpenWFE
51
52
 
52
- #
53
- # A parent class for CronExpression and SleepExpression, is never
54
- # used directly.
55
- # It contains a simple get_scheduler() method simplifying the scheduler
56
- # localization for <sleep/> and <cron/>.
57
- #
58
- class TimeExpression < FlowExpression
59
- include Schedulable
60
-
61
- attr_accessor \
62
- :applied_workitem,
63
- :scheduler_job_id
64
-
65
- #
66
- # Makes sure to cancel any scheduler job associated with this
67
- # expression
68
- #
69
- def cancel ()
70
- synchronize do
71
-
72
- ldebug { "cancel()..." }
73
-
74
- unschedule()
75
-
76
- return super()
77
- end
78
- end
79
-
80
- def unschedule ()
81
-
82
- ldebug { "unschedule() @scheduler_job_id is #{@scheduler_job_id}" }
83
-
84
- get_scheduler.unschedule(@scheduler_job_id) \
85
- if @scheduler_job_id
86
- end
87
-
88
- protected
89
-
90
- #
91
- # Will return true if this TimeExpression has a
92
- # 'scheduler_job_ib' and this job is this expression's job.
93
- #
94
- # The job_id is specifiable, so that this method can also be
95
- # used by the 'when' expression for example.
96
- #
97
- def already_scheduled? (job_id=nil)
98
-
99
- job_id = @scheduler_job_id unless job_id
100
-
101
- s = get_scheduler.get_schedulable job_id
102
-
103
- return (s and s.fei == self.fei)
104
- end
105
- end
106
-
107
53
  #
108
54
  # The 'sleep' expression expects one attribute, either 'for', either
109
55
  # 'until'.
@@ -129,9 +75,8 @@ module OpenWFE
129
75
  sfor = lookup_attribute(:for, workitem)
130
76
  suntil = lookup_attribute(:until, workitem)
131
77
 
132
- if sfor == nil and suntil == nil
133
- sfor = OpenWFE::fetch_text_content(self, workitem)
134
- end
78
+ sfor = fetch_text_content(workitem) \
79
+ if sfor == nil and suntil == nil
135
80
 
136
81
  #ldebug { "apply() sfor is '#{sfor}'" }
137
82
  #ldebug { "apply() suntil is '#{suntil}'" }
@@ -42,7 +42,6 @@
42
42
  #require 'uri'
43
43
 
44
44
  require 'openwfe/utils'
45
- require 'openwfe/expressions/fe_utils'
46
45
 
47
46
 
48
47
  #
@@ -90,7 +89,7 @@ module OpenWFE
90
89
 
91
90
  def apply (workitem)
92
91
 
93
- ref = OpenWFE::lookup_ref(self, workitem)
92
+ ref = lookup_ref(workitem)
94
93
 
95
94
  raise "'subprocess' expression misses a 'ref', 'field-ref' or 'variable-ref' attribute" unless ref
96
95
 
@@ -114,13 +113,15 @@ module OpenWFE
114
113
 
115
114
  params = lookup_attributes(workitem)
116
115
 
117
- text = OpenWFE::fetch_text_content(self, workitem, false)
116
+ text = fetch_text_content(workitem, false)
118
117
  params["0"] = text if text
119
118
 
119
+ #puts
120
120
  #puts " ... params are #{params.keys.join(', ')}"
121
+ #puts " ... values are #{params.values.join(', ')}"
121
122
 
122
- get_expression_pool()\
123
- .launch_template(requester, 0, template, workitem, params)
123
+ get_expression_pool.launch_template(
124
+ requester, get_next_sub_id, template, workitem, params)
124
125
  end
125
126
 
126
127
  #def reply (workitem)
@@ -41,9 +41,7 @@
41
41
 
42
42
  require 'openwfe/workitem'
43
43
  require 'openwfe/flowexpressionid'
44
- require 'openwfe/expressions/condition'
45
44
  require 'openwfe/expressions/flowexpression'
46
- require 'openwfe/expressions/fe_utils'
47
45
 
48
46
 
49
47
  #
@@ -52,6 +50,17 @@ require 'openwfe/expressions/fe_utils'
52
50
 
53
51
  module OpenWFE
54
52
 
53
+ #
54
+ # The 'set' expression is used to set the value of a (process) variable or
55
+ # a (workitem) field.
56
+ #
57
+ # <set field="price" value="CHF 12.00" />
58
+ # <set variable="/stage" value="3" />
59
+ # <set variable="/stage" field-value="f_stage" />
60
+ # <set field="stamp" value="${r:Time.now.to_i}" />
61
+ #
62
+ # (Notice the usage of the dollar notation in the last exemple).
63
+ #
55
64
  class SetValueExpression < FlowExpression
56
65
 
57
66
  names :set
@@ -59,8 +68,7 @@ module OpenWFE
59
68
  def apply (workitem)
60
69
 
61
70
  if @children.length < 1
62
- workitem.attributes[FIELD_RESULT] = \
63
- OpenWFE::lookup_value(self, workitem)
71
+ workitem.attributes[FIELD_RESULT] = lookup_value(workitem)
64
72
  reply(workitem)
65
73
  return
66
74
  end
@@ -73,8 +81,7 @@ module OpenWFE
73
81
  end
74
82
 
75
83
  #workitem.attributes[FIELD_RESULT] = child.to_s
76
- workitem.attributes[FIELD_RESULT] = \
77
- OpenWFE::fetch_text_content(self, workitem)
84
+ workitem.attributes[FIELD_RESULT] = fetch_text_content(workitem)
78
85
 
79
86
  reply(workitem)
80
87
  end
@@ -123,10 +130,16 @@ module OpenWFE
123
130
  # return child
124
131
  # end
125
132
  # end
126
- # return OpenWFE::lookup_value(self, workitem)
133
+ # return lookup_value(workitem)
127
134
  #end
128
135
  end
129
136
 
137
+ #
138
+ # 'unset' removes a field or a variable.
139
+ #
140
+ # unset :field => "price"
141
+ # unset :variable => "eval_result"
142
+ #
130
143
  class UnsetValueExpression < FlowExpression
131
144
 
132
145
  names :unset
@@ -151,119 +164,5 @@ module OpenWFE
151
164
  #end
152
165
  end
153
166
 
154
- class ComparisonExpression < FlowExpression
155
-
156
- def apply (workitem)
157
-
158
- value_a = OpenWFE::lookup_value(self, workitem)
159
- value_b = OpenWFE::lookup_value(self, workitem, 'other')
160
-
161
- result = compare(value_a, value_b)
162
-
163
- ldebug { "apply() result is '#{result}' #{@fei.to_debug_s}" }
164
-
165
- OpenWFE::set_result(workitem, result)
166
-
167
- reply_to_parent(workitem)
168
- end
169
-
170
- protected
171
-
172
- def compare (a, b)
173
- raise "not yet implemented : '#{@fei.expressionName}'"
174
- end
175
- end
176
-
177
- #
178
- # <equals/>
179
- #
180
- class EqualsExpression < ComparisonExpression
181
-
182
- names :equals
183
-
184
- protected
185
-
186
- def compare (a, b)
187
- #ldebug { "compare() #{fei.to_debug_s}" }
188
- #ldebug { "compare() '#{a}' == '#{b}'" }
189
- return a == b
190
- end
191
- end
192
-
193
- #
194
- # <if/>
195
- #
196
- class IfExpression < FlowExpression
197
- include ConditionMixin
198
-
199
- names :if
200
-
201
- attr_accessor \
202
- :condition_replied
203
-
204
- def apply (workitem)
205
-
206
- reply_to_parent(workitem) if @children.length < 1
207
-
208
- test = eval_condition(:test, workitem)
209
-
210
- @condition_replied = (test != nil)
211
- #
212
- # if the "test" attribute is not used, test will be null
213
-
214
- store_itself()
215
-
216
- if test != nil
217
- apply_consequence(test, workitem, 0)
218
- else
219
- get_expression_pool.apply(@children[0], workitem)
220
- end
221
- end
222
-
223
- def reply (workitem)
224
-
225
- if @condition_replied
226
- reply_to_parent(workitem)
227
- return
228
- end
229
-
230
- result = workitem.attributes[FIELD_RESULT]
231
-
232
- @condition_replied = true
233
-
234
- store_itself()
235
-
236
- apply_consequence(result, workitem)
237
- end
238
-
239
- def reply_to_parent(workitem)
240
- clean_children()
241
- super(workitem)
242
- end
243
-
244
- protected
245
-
246
- def apply_consequence (index, workitem, offset=1)
247
-
248
- if index == true
249
- index = 0
250
- elsif index == false
251
- index = 1
252
- elsif index == nil
253
- index = 1
254
- elsif not index.integer?
255
- index = 0
256
- end
257
-
258
- index = index + offset
259
-
260
- if index >= @children.length
261
- reply_to_parent(workitem)
262
- else
263
- get_expression_pool.apply(@children[index], workitem)
264
- end
265
- end
266
- end
267
-
268
167
  end
269
168
 
@@ -0,0 +1,79 @@
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/time'
43
+
44
+
45
+ module OpenWFE
46
+
47
+ #
48
+ # The 'wait' expression simply blocks/waits until the given condition
49
+ # evaluates to true.
50
+ # This expression accepts a timeout (else it will block ad eternam).
51
+ #
52
+ # sequence do
53
+ # wait :until => "${done} == true"
54
+ # participant :toto
55
+ # end
56
+ #
57
+ # Participant 'toto' will receive a workitem after the variable 'done' is
58
+ # set to true (somewhere else in the process definition).
59
+ #
60
+ # sequence do
61
+ # wait :runtil => "Time.new.to_i % 7 == 0"
62
+ # participant :toto
63
+ # end
64
+ #
65
+ # Participant 'toto' will receive a workitem after a certain condition
66
+ # expressed directly in Ruby evaluates to true.
67
+ #
68
+ # 'wait' is different than 'when' : when it times out (if a timeout is set,
69
+ # the block ceases and the flow resumes. On a timeout, 'when' will not
70
+ # execute its nested 'consequence' child.
71
+ #
72
+ class WaitExpression < WaitingExpression
73
+
74
+ names :wait
75
+ conditions :until
76
+ end
77
+
78
+ end
79
+
@@ -39,17 +39,16 @@
39
39
  # John Mettraux at openwfe.org
40
40
  #
41
41
 
42
- #require 'openwfe/rudefinitions'
43
42
  require 'openwfe/utils'
44
43
  require 'openwfe/util/otime'
45
44
  require 'openwfe/util/scheduler'
45
+ require 'openwfe/expressions/time'
46
46
  require 'openwfe/expressions/timeout'
47
47
  require 'openwfe/expressions/condition'
48
- require 'openwfe/expressions/fe_sleep'
49
48
 
50
49
 
51
50
  #
52
- # expressions like 'sleep' and 'cron'
51
+ # 'when' and 'wait'
53
52
  #
54
53
 
55
54
  module OpenWFE
@@ -65,129 +64,65 @@ module OpenWFE
65
64
  # where the participant "toto" will receive a workitem when the (local)
66
65
  # variable "over" has the value true.
67
66
  #
68
- class WhenExpression < TimeExpression
69
- include ConditionMixin, TimeoutMixin
67
+ # This is also possible :
68
+ #
69
+ # <when>
70
+ # <equals field-value="done" other-value="true" />
71
+ # <participant ref="toto" />
72
+ # </when>
73
+ #
74
+ # The 'when' expression by defaults, evaluates every 10 seconds its
75
+ # condition clause.
76
+ # A different frequency can be stated via the "frequency" attribute :
77
+ #
78
+ # when :test => "${completion_level} == 4", :frequency => "1s"
79
+ # participant "next_stage"
80
+ # end
81
+ #
82
+ # will check for the completion_level value every second. The scheduler
83
+ # itself is by default 'waking up' every 250 ms, so setting a frequency to
84
+ # something smaller than that value might prove useless.
85
+ #
86
+ class WhenExpression < WaitingExpression
70
87
 
71
88
  names :when
89
+ conditions :test
72
90
 
73
91
  attr_accessor \
74
- :frequency,
75
- :consequence_triggered
92
+ :consequence_triggered,
93
+ :condition_sub_id
76
94
 
77
95
  DEFAULT_FREQUENCY = "10s"
78
96
 
79
97
  def apply (workitem)
80
98
 
81
- remove_timedout_flag(workitem)
82
-
83
99
  if @children.size < 1
84
- reply_to_parent(workitem)
100
+ reply_to_parent workitem
85
101
  return
86
102
  end
87
103
 
88
- @applied_workitem = workitem.dup
89
-
90
- @frequency =
91
- lookup_attribute(:frequency, workitem, DEFAULT_FREQUENCY)
92
- @frequency =
93
- OpenWFE::parse_time_string(@frequency)
94
-
95
- determine_timeout()
96
-
104
+ @condition_sub_id = -1
97
105
  @consequence_triggered = false
98
106
 
99
- store_itself()
100
-
101
- trigger(nil)
107
+ super(workitem)
102
108
  end
103
109
 
104
110
  def reply (workitem)
105
111
 
106
- ldebug do
107
- "reply() @consequence_triggered is '#{@consequence_triggered}'"
108
- end
112
+ #ldebug do
113
+ # "reply() @consequence_triggered is '#{@consequence_triggered}'"
114
+ #end
109
115
 
110
116
  if @consequence_triggered
111
117
  reply_to_parent(workitem)
112
118
  return
113
119
  end
114
120
 
115
- result = OpenWFE::get_result(workitem)
116
-
117
- if result
118
- apply_consequence(workitem)
119
- else
120
- reschedule(get_scheduler)
121
- end
122
- end
123
-
124
- def cancel ()
125
- to_unschedule()
126
- super()
127
- end
128
-
129
- def trigger (params)
130
-
131
- ldebug { "trigger() #{@fei.to_debug_s} params is #{params}" }
132
-
133
- if params == :do_timeout!
134
- #
135
- # do timeout...
136
- #
137
- set_timedout_flag(@applied_workitem)
138
- reply_to_parent(@applied_workitem)
139
- return
140
- end
141
-
142
- @scheduler_job_id = nil
143
-
144
- evaluate_condition()
145
- end
146
-
147
- def reschedule (scheduler)
148
-
149
- #return unless @applied_workitem
150
-
151
- @scheduler_job_id =
152
- scheduler.schedule_in(@frequency, self, nil)
153
-
154
- ldebug { "reschedule() @scheduler_job_id is #{@scheduler_job_id}" }
155
-
156
- to_reschedule(scheduler)
157
- end
158
-
159
- def reply_to_parent (workitem)
160
-
161
- unschedule()
162
- unschedule_timeout()
163
-
164
121
  super(workitem)
165
122
  end
166
123
 
167
124
  protected
168
125
 
169
- def evaluate_condition
170
-
171
- if @children.size > 1
172
- #
173
- # trigger the evaluation of the first (condition) child
174
-
175
- store_itself()
176
-
177
- get_expression_pool.launch_template(
178
- self, @children[0], @applied_workitem)
179
- else
180
- #
181
- # eval the attribute condition immediately
182
-
183
- c = eval_condition(:test, @applied_workitem)
184
-
185
- OpenWFE::set_result(@applied_workitem, c)
186
-
187
- reply(@applied_workitem)
188
- end
189
- end
190
-
191
126
  def apply_consequence (workitem)
192
127
 
193
128
  @consequence_triggered = true