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
@@ -0,0 +1,262 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2006-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/workitem'
43
+ require 'openwfe/flowexpressionid'
44
+ require 'openwfe/expressions/condition'
45
+ require 'openwfe/expressions/flowexpression'
46
+
47
+
48
+ #
49
+ # expressions like 'set' and 'unset' and their utility methods
50
+ #
51
+
52
+ module OpenWFE
53
+
54
+ #
55
+ # The 'if' expression.
56
+ #
57
+ # <if>
58
+ # <equals field-value="f0" other-value="true" />
59
+ # <!-- then -->
60
+ # <participant ref="alpha" />
61
+ # </if>
62
+ #
63
+ # It accepts an 'else' clause :
64
+ #
65
+ # <if>
66
+ # <equals field-value="f0" other-value="true" />
67
+ # <!-- then -->
68
+ # <participant ref="alpha" />
69
+ # <!-- else -->
70
+ # <participant ref="bravo" />
71
+ # </if>
72
+ #
73
+ # The 'test' attribute can be used instead of a condition child :
74
+ #
75
+ # <if test="${f:f0}">
76
+ # <!-- then -->
77
+ # <participant ref="alpha" />
78
+ # </if>
79
+ #
80
+ # The 'rtest' attribute can be used to embed a condition expressed directly
81
+ # in Ruby :
82
+ #
83
+ # <if rtest="5 * 12 == 61">
84
+ # <!-- then -->
85
+ # <participant ref="alpha" />
86
+ # </if>
87
+ #
88
+ # Used alone with 'test' or 'rtest', the 'if' expression simply sets the
89
+ # the __result__ field of its workitem to the result of its attribute
90
+ # evaluation :
91
+ #
92
+ # <if test="5 == 6"/>
93
+ #
94
+ # will set the __result__ field of the workitem to 'false'.
95
+ #
96
+ class IfExpression < FlowExpression
97
+ include ConditionMixin
98
+
99
+ names :if
100
+
101
+ attr_accessor \
102
+ :condition_replied
103
+
104
+ def apply (workitem)
105
+
106
+ workitem.unset_result
107
+
108
+ test = eval_condition(:test, workitem)
109
+
110
+ if @children.length < 1
111
+ workitem.set_result test if test
112
+ reply_to_parent(workitem)
113
+ return
114
+ end
115
+
116
+ @condition_replied = (test != nil)
117
+ #
118
+ # if the "test" attribute is not used, test will be null
119
+
120
+ store_itself()
121
+
122
+ if test != nil
123
+ apply_consequence(test, workitem, 0)
124
+ else
125
+ get_expression_pool.apply(@children[0], workitem)
126
+ end
127
+ end
128
+
129
+ def reply (workitem)
130
+
131
+ if @condition_replied
132
+ reply_to_parent(workitem)
133
+ return
134
+ end
135
+
136
+ result = workitem.attributes[FIELD_RESULT]
137
+
138
+ @condition_replied = true
139
+
140
+ store_itself()
141
+
142
+ apply_consequence result, workitem
143
+ end
144
+
145
+ def reply_to_parent(workitem)
146
+ clean_children()
147
+ super workitem
148
+ end
149
+
150
+ protected
151
+
152
+ def apply_consequence (index, workitem, offset=1)
153
+
154
+ if index == true
155
+ index = 0
156
+ elsif index == false
157
+ index = 1
158
+ elsif index == nil
159
+ index = 1
160
+ elsif not index.integer?
161
+ index = 0
162
+ end
163
+
164
+ index = index + offset
165
+
166
+ if index >= @children.length
167
+ reply_to_parent workitem
168
+ else
169
+ get_expression_pool.apply @children[index], workitem
170
+ end
171
+ end
172
+ end
173
+
174
+ #
175
+ # The 'case' expression.
176
+ #
177
+ # <case>
178
+ #
179
+ # <equals field="f0" other-value="ready" />
180
+ # <participant ref="alpha" />
181
+ #
182
+ # <if test="${supply_level} == ${field:supply_request}" />
183
+ # <participant ref="bravo" />
184
+ #
185
+ # <!-- optional else -->
186
+ # <participant ref="charly" />
187
+ #
188
+ # </case>
189
+ #
190
+ # A generalized 'if'. Will evaluate its children, expecting the order :
191
+ #
192
+ # - condition
193
+ # - consequence
194
+ # - condition
195
+ # - consequence
196
+ # ...
197
+ # - else consequence (optional)
198
+ #
199
+ # The 'switch' nickname can be used for 'case'.
200
+ #
201
+ class CaseExpression < FlowExpression
202
+
203
+ names :case, :switch
204
+
205
+ attr_accessor \
206
+ :offset,
207
+ :evaluating_condition
208
+
209
+ def apply (workitem)
210
+
211
+ workitem.unset_result
212
+
213
+ @offset = nil
214
+
215
+ trigger_child workitem, true
216
+ end
217
+
218
+ def reply (workitem)
219
+
220
+ if @evaluating_condition
221
+
222
+ result = workitem.get_boolean_result
223
+
224
+ #ldebug { "reply() result : '#{result.to_s}' (#{result.class})" }
225
+
226
+ trigger_child workitem, !result
227
+ else
228
+
229
+ reply_to_parent workitem
230
+ end
231
+ end
232
+
233
+ protected
234
+
235
+ def trigger_child (workitem, is_condition)
236
+
237
+ @offset = if !@offset
238
+ 0
239
+ elsif is_condition
240
+ @offset + 2
241
+ else
242
+ @offset + 1
243
+ end
244
+
245
+ #ldebug { "trigger_child() is_condition ? #{is_condition}" }
246
+ #ldebug { "trigger_child() next offset is #{@offset}" }
247
+
248
+ unless @children[@offset]
249
+ reply_to_parent workitem
250
+ return
251
+ end
252
+
253
+ @evaluating_condition = is_condition
254
+
255
+ store_itself
256
+
257
+ get_expression_pool.apply(@children[@offset], workitem)
258
+ end
259
+ end
260
+
261
+ end
262
+
@@ -40,7 +40,6 @@
40
40
  #
41
41
 
42
42
  require 'openwfe/expressions/flowexpression'
43
- require 'openwfe/expressions/fe_utils'
44
43
 
45
44
 
46
45
  module OpenWFE
@@ -93,7 +92,7 @@ module OpenWFE
93
92
  store_itself()
94
93
 
95
94
  get_expression_pool.launch_template(
96
- self, 0, @children[0], workitem, nil)
95
+ self, @iterator.counter-1, @children[0], workitem, nil)
97
96
  end
98
97
  end
99
98
 
@@ -125,8 +124,8 @@ module OpenWFE
125
124
 
126
125
  @counter = 0
127
126
 
128
- raw_list = OpenWFE::lookup_vf_attribute(
129
- iterator_expression, workitem, :value, :on)
127
+ raw_list = iterator_expression.lookup_vf_attribute(
128
+ workitem, :value, :on)
130
129
 
131
130
  @iteration_list = extract_iteration_list(raw_list)
132
131
 
@@ -40,7 +40,6 @@
40
40
  #
41
41
 
42
42
  require 'openwfe/expressions/flowexpression'
43
- require 'openwfe/expressions/fe_utils'
44
43
 
45
44
 
46
45
  module OpenWFE
@@ -41,7 +41,6 @@
41
41
 
42
42
  require 'openwfe/util/safe'
43
43
  require 'openwfe/expressions/flowexpression'
44
- require 'openwfe/expressions/fe_utils'
45
44
 
46
45
 
47
46
  module OpenWFE
@@ -57,7 +56,7 @@ module OpenWFE
57
56
 
58
57
  escape = lookup_boolean_attribute('escape', workitem, false)
59
58
 
60
- text = OpenWFE::fetch_text_content(self, workitem, escape)
59
+ text = fetch_text_content(workitem, escape)
61
60
  text << "\n"
62
61
 
63
62
  tracer = @application_context['__tracer']
@@ -109,9 +108,9 @@ module OpenWFE
109
108
 
110
109
  escape = lookup_boolean_attribute('escape', workitem, false)
111
110
 
112
- code = OpenWFE::lookup_vf_attribute(self, workitem, 'code')
111
+ code = lookup_vf_attribute(workitem, 'code')
113
112
 
114
- code = OpenWFE::fetch_text_content(self, workitem, escape) \
113
+ code = fetch_text_content(workitem, escape) \
115
114
  unless code
116
115
 
117
116
  code = code.to_s
@@ -119,7 +118,7 @@ module OpenWFE
119
118
  #result = eval(code)
120
119
  result = OpenWFE::eval_safely(code, SAFETY_LEVEL, binding())
121
120
 
122
- OpenWFE::set_result(workitem, result) \
121
+ workitem.set_result(result) \
123
122
  if result != nil # 'false' is a valid result
124
123
 
125
124
  reply_to_parent(workitem)
@@ -42,7 +42,6 @@
42
42
  require 'openwfe/utils'
43
43
  require 'openwfe/rudefinitions'
44
44
  require 'openwfe/expressions/timeout'
45
- require 'openwfe/expressions/fe_utils'
46
45
 
47
46
 
48
47
  #
@@ -75,9 +74,9 @@ module OpenWFE
75
74
 
76
75
  @applied_workitem = workitem.dup
77
76
 
78
- @participant_name = OpenWFE::lookup_ref(self, workitem)
77
+ @participant_name = lookup_ref(workitem)
79
78
 
80
- @participant_name = OpenWFE::fetch_text_content(self, workitem) \
79
+ @participant_name = fetch_text_content(workitem) \
81
80
  unless @participant_name
82
81
 
83
82
  determine_timeout()
@@ -81,12 +81,15 @@ module OpenWFE
81
81
 
82
82
  attributes = extract_attributes() unless attributes
83
83
 
84
+
84
85
  expression = exp_class.new(
85
86
  @fei,
86
87
  @parent_id,
87
88
  @environment_id,
88
89
  @application_context,
89
90
  attributes)
91
+
92
+ consider_tag(workitem, expression)
90
93
 
91
94
  handle_descriptions()
92
95
 
@@ -117,17 +120,19 @@ module OpenWFE
117
120
  template = get_participant_map.lookup_participant(exp_name)
118
121
  end
119
122
  end
120
- #
121
- # is it a directly a participant ?
123
+ #
124
+ # is it a directly a participant ?
122
125
 
123
126
  if template
124
127
 
125
128
  if template.kind_of? OpenWFE::FlowExpressionId
126
- launch_template(template, workitem)
127
- return
128
- end
129
129
 
130
- if template.kind_of? OpenWFE::Participant
130
+ exp_class = OpenWFE::SubProcessRefExpression
131
+ attributes = extract_attributes()
132
+ attributes["ref"] = exp_name
133
+
134
+ elsif template.kind_of? OpenWFE::Participant
135
+
131
136
  exp_class = OpenWFE::ParticipantExpression
132
137
  attributes = extract_attributes()
133
138
  attributes["ref"] = exp_name
@@ -163,19 +168,19 @@ module OpenWFE
163
168
  #end
164
169
 
165
170
  def is_definition? ()
166
- return get_expression_map.is_definition?(expression_name())
171
+ get_expression_map.is_definition?(expression_name())
167
172
  end
168
173
 
169
174
  def expression_class ()
170
- return get_expression_map.get_class(expression_name())
175
+ get_expression_map.get_class(expression_name())
171
176
  end
172
177
 
173
178
  def definition_name ()
174
- return raw_representation.attributes['name'].to_s
179
+ raw_representation.attributes['name'].to_s
175
180
  end
176
181
 
177
182
  def expression_name ()
178
- return raw_representation.name
183
+ raw_representation.name
179
184
  end
180
185
 
181
186
  protected
@@ -206,27 +211,19 @@ module OpenWFE
206
211
  unless default
207
212
  end
208
213
 
209
- def launch_template (template, workitem)
210
-
211
- @attributes = extract_attributes()
212
-
213
- #require 'pp'
214
- #pp attributes
215
- #pp lookup_attributes(workitem, attributes)
216
-
217
- params = lookup_attributes(workitem)
218
-
219
- extract_text_children.each_with_index do |value, index|
220
- params[index.to_s] = value
221
- end
222
-
223
- get_expression_pool().launch_template(
224
- self,
225
- 0,
226
- template,
227
- workitem,
228
- params)
229
- end
214
+ #def launch_template (template, workitem)
215
+ # @attributes = extract_attributes()
216
+ # params = lookup_attributes(workitem)
217
+ # extract_text_children.each_with_index do |value, index|
218
+ # params[index.to_s] = value
219
+ # end
220
+ # get_expression_pool().launch_template(
221
+ # self,
222
+ # get_next_sub_id,
223
+ # template,
224
+ # workitem,
225
+ # params)
226
+ #end
230
227
 
231
228
  def extract_attributes ()
232
229
  raise NotImplementedError.new("'abstract method' sorry")
@@ -244,6 +241,49 @@ module OpenWFE
244
241
  raise NotImplementedError.new("'abstract method' sorry")
245
242
  end
246
243
 
244
+ #
245
+ # Expressions can get tagged. Tagged expressions can easily
246
+ # be cancelled (undone) or redone.
247
+ #
248
+ def consider_tag (workitem, new_expression)
249
+
250
+ tagname = new_expression.lookup_attribute(:tag, workitem)
251
+
252
+ return unless tagname
253
+
254
+ ldebug { "consider_tag() tag is '#{tagname}'" }
255
+
256
+ set_variable(tagname, Tag.new(self, workitem))
257
+ #
258
+ # keep copy of raw expression and workitem as applied
259
+
260
+ new_expression.attributes["tag"] = tagname
261
+ #
262
+ # making sure that the value of tag doesn't change anymore
263
+ end
264
+
265
+ #
266
+ # A small class wrapping a tag (a raw expression and the workitem
267
+ # it received at apply time.
268
+ #
269
+ class Tag
270
+
271
+ attr_reader \
272
+ :raw_expression,
273
+ :workitem
274
+
275
+ def flow_expression_id
276
+ @raw_expression.fei
277
+ end
278
+ alias :fei :flow_expression_id
279
+
280
+ def initialize (raw_expression, workitem)
281
+
282
+ @raw_expression = raw_expression.dup
283
+ @workitem = workitem.dup
284
+ end
285
+ end
286
+
247
287
  #
248
288
  # Encapsulating
249
289
  # <parameter field="x" default="y" type="z" match="m" />
@@ -0,0 +1,141 @@
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 'thread'
43
+ require 'openwfe/expressions/fe_when'
44
+
45
+
46
+ module OpenWFE
47
+
48
+ #
49
+ # The 'reserve' expression ensures that its nested child expression
50
+ # executes while a reserved mutex is set.
51
+ #
52
+ # Thus
53
+ #
54
+ # concurrence do
55
+ # reserve :mutex => :m0 do
56
+ # sequence do
57
+ # participant :alpha
58
+ # participant :bravo
59
+ # end
60
+ # end
61
+ # reserve :mutex => :m0 do
62
+ # participant :charly
63
+ # end
64
+ # participant :delta
65
+ # end
66
+ #
67
+ # The sequence will not but run while the participant charly is active
68
+ # and vice versa. The participant delta is not concerned.
69
+ #
70
+ # The mutex is a regular variable name, thus a mutex named "//toto" could
71
+ # be used to prevent segemnts of totally different process instances from
72
+ # running.
73
+ #
74
+ class ReserveExpression < WhenExpression
75
+
76
+ #
77
+ # A mutex for the whole class, it's meant to prevent 'reserve'
78
+ # from reserving a workflow mutex simultaneaously.
79
+ #
80
+ @@mutex = Mutex.new
81
+
82
+ names :reserve
83
+
84
+ attr_accessor :mutex_name
85
+
86
+ def apply (workitem)
87
+
88
+ if @children.size < 1
89
+ reply_to_parent workitem
90
+ return
91
+ end
92
+
93
+ @mutex_name = lookup_attribute :mutex, workitem
94
+
95
+ super
96
+ end
97
+
98
+ def reply (workitem)
99
+
100
+ @@mutex.synchronize do
101
+
102
+ delete_variable @mutex_name \
103
+ if @consequence_triggered
104
+ #
105
+ # unset mutex
106
+ end
107
+
108
+ super workitem
109
+ end
110
+
111
+ protected
112
+
113
+ def evaluate_condition
114
+
115
+ mutex = nil
116
+
117
+ @@mutex.synchronize do
118
+
119
+ mutex = lookup_variable @mutex_name
120
+
121
+ set_variable @mutex_name, fei.to_s \
122
+ unless mutex
123
+ #
124
+ # reserve mutex
125
+ end
126
+
127
+ do_reply (mutex == nil)
128
+ end
129
+
130
+ def apply_consequence (workitem)
131
+
132
+ @consequence_triggered = true
133
+
134
+ store_itself()
135
+
136
+ get_expression_pool.apply(@children[0], workitem)
137
+ end
138
+ end
139
+
140
+ end
141
+
@@ -40,7 +40,6 @@
40
40
  #
41
41
 
42
42
  require 'openwfe/expressions/flowexpression'
43
- require 'openwfe/expressions/fe_utils'
44
43
 
45
44
 
46
45
  #