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
@@ -0,0 +1,127 @@
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
+
44
+
45
+ #
46
+ # 'timeout' as a simple expression
47
+ #
48
+
49
+ module OpenWFE
50
+
51
+ #
52
+ # The timeout concept begun with the participant expression. When a
53
+ # participant doesn't reply for a certain amount of time, a specified
54
+ # timeout can get triggered.
55
+ # Sometimes something more complex than a single participant needs a
56
+ # timeout setting, this expression sets a timeout for the expression[s]
57
+ # nested within it.
58
+ #
59
+ # <timeout after="2d">
60
+ # <sequence>
61
+ # (...)
62
+ # </sequence>
63
+ # </timeout>
64
+ #
65
+ class TimeoutExpression < FlowExpression
66
+ include TimeoutMixin
67
+
68
+ names :timeout
69
+
70
+ attr_accessor :applied_workitem
71
+
72
+ def apply (workitem)
73
+
74
+ if @children.size < 1
75
+ reply_to_parent workitem
76
+ return
77
+ end
78
+
79
+ @applied_workitem = workitem.dup
80
+
81
+ schedule_timeout(:after)
82
+
83
+ get_expression_pool.apply @children[0], workitem
84
+ end
85
+
86
+ #
87
+ # The child expression replies, make sure to unschedule the timeout
88
+ # before replying (to our own parent expression).
89
+ #
90
+ def reply (workitem)
91
+
92
+ unschedule_timeout()
93
+
94
+ super
95
+ end
96
+
97
+ #
98
+ # Cancel order : cancels the child expression (if applied) and
99
+ # unschedule the timeout (if any).
100
+ #
101
+ def cancel
102
+
103
+ get_expression_pool.cancel(@children[0]) if @applied_workitem
104
+
105
+ unschedule_timeout()
106
+
107
+ super
108
+ end
109
+
110
+ #
111
+ # The timeout trigger, cancels the nested process segment (the
112
+ # nested expression).
113
+ #
114
+ def trigger (scheduler)
115
+
116
+ ldebug { "trigger() timeout requested for #{@fei.to_debug_s}" }
117
+
118
+ set_timedout_flag(@applied_workitem)
119
+
120
+ cancel()
121
+
122
+ reply_to_parent @applied_workitem
123
+ end
124
+ end
125
+
126
+ end
127
+
@@ -75,13 +75,25 @@ module OpenWFE
75
75
  # condition clause.
76
76
  # A different frequency can be stated via the "frequency" attribute :
77
77
  #
78
- # when :test => "${completion_level} == 4", :frequency => "1s"
78
+ # _when :test => "${completion_level} == 4", :frequency => "1s"
79
79
  # participant "next_stage"
80
80
  # end
81
81
  #
82
82
  # will check for the completion_level value every second. The scheduler
83
83
  # itself is by default 'waking up' every 250 ms, so setting a frequency to
84
84
  # something smaller than that value might prove useless.
85
+ # (Note than in the Ruby process definition, the 'when' got escaped to
86
+ # '_when' not to conflict with the 'when' keyword of the Ruby language).
87
+ #
88
+ # The when expression understands the 'timeout' attribute like the
89
+ # participant expression does. Thus
90
+ #
91
+ # _when :test => "${cows} == 'do fly'", :timeout => "1y"
92
+ # participant "me"
93
+ # end
94
+ #
95
+ # will timeout after one year (participant "me" will not receive a
96
+ # workitem).
85
97
  #
86
98
  class WhenExpression < WaitingExpression
87
99
 
@@ -162,7 +162,7 @@ module OpenWFE
162
162
  # simply if the expression got swapped out of memory and reloaded later.
163
163
  #
164
164
  def store_itself
165
- ldebug { "store_itself() for #{@fei.to_debug_s}" }
165
+ #ldebug { "store_itself() for #{@fei.to_debug_s}" }
166
166
  #ldebug { "store_itself() \n#{OpenWFE::caller_to_s(0, 6)}" }
167
167
  get_expression_pool.update self
168
168
  end
@@ -499,6 +499,9 @@ module OpenWFE
499
499
  children.each do |child|
500
500
  if child.kind_of?(RawExpression)
501
501
  text << child.fei.to_s
502
+ elsif child.kind_of?(FlowExpressionId)
503
+ text << get_expression_pool\
504
+ .fetch_expression(child).raw_representation.to_s
502
505
  else
503
506
  text << child.to_s
504
507
  end
@@ -70,7 +70,7 @@ module OpenWFE
70
70
 
71
71
  unschedule()
72
72
 
73
- return super()
73
+ super()
74
74
  end
75
75
  end
76
76
 
@@ -81,24 +81,6 @@ module OpenWFE
81
81
  get_scheduler.unschedule(@scheduler_job_id) \
82
82
  if @scheduler_job_id
83
83
  end
84
-
85
- protected
86
-
87
- #
88
- # Will return true if this TimeExpression has a
89
- # 'scheduler_job_ib' and this job is this expression's job.
90
- #
91
- # The job_id is specifiable, so that this method can also be
92
- # used by the 'when' expression for example.
93
- #
94
- def already_scheduled? (job_id=nil)
95
-
96
- job_id = @scheduler_job_id unless job_id
97
-
98
- s = get_scheduler.get_schedulable job_id
99
-
100
- return (s and s.fei == self.fei)
101
- end
102
84
  end
103
85
 
104
86
  #
@@ -146,7 +128,7 @@ module OpenWFE
146
128
 
147
129
  store_itself()
148
130
 
149
- trigger(nil)
131
+ trigger()
150
132
  end
151
133
 
152
134
  def reply (workitem)
@@ -165,16 +147,16 @@ module OpenWFE
165
147
  super()
166
148
  end
167
149
 
168
- def trigger (params)
150
+ def trigger (params={})
169
151
 
170
152
  ldebug { "trigger() #{@fei.to_debug_s} params is #{params}" }
171
153
 
172
- if params == :do_timeout!
154
+ if params[:do_timeout!]
173
155
  #
174
156
  # do timeout...
175
157
  #
176
- set_timedout_flag(@applied_workitem)
177
- reply_to_parent(@applied_workitem)
158
+ set_timedout_flag @applied_workitem
159
+ reply_to_parent @applied_workitem
178
160
  return
179
161
  end
180
162
 
@@ -185,10 +167,11 @@ module OpenWFE
185
167
 
186
168
  def reschedule (scheduler)
187
169
 
188
- #return unless @applied_workitem
170
+ @scheduler_job_id = "waiting_#{fei.to_s}"
189
171
 
190
- @scheduler_job_id =
191
- scheduler.schedule_in(@frequency, self, nil)
172
+ scheduler.schedule_in(
173
+ @frequency,
174
+ { :schedulable => self, :job_id => @scheduler_job_id })
192
175
 
193
176
  ldebug { "reschedule() @scheduler_job_id is #{@scheduler_job_id}" }
194
177
 
@@ -85,6 +85,15 @@ module OpenWFE
85
85
  to_reschedule(scheduler)
86
86
  end
87
87
 
88
+ #
89
+ # Combines a call to determine_timeout and to reschedule.
90
+ #
91
+ def schedule_timeout (timeout_attname=:timeout)
92
+
93
+ determine_timeout(timeout_attname)
94
+ to_reschedule(get_scheduler)
95
+ end
96
+
88
97
  #
89
98
  # Overrides the parent method to make sure a potential
90
99
  # timeout schedules gets removed.
@@ -118,7 +127,7 @@ module OpenWFE
118
127
  #
119
128
  def to_reschedule (scheduler)
120
129
 
121
- return if @timeout_job_id
130
+ #return if @timeout_job_id
122
131
  #
123
132
  # already rescheduled
124
133
 
@@ -126,12 +135,19 @@ module OpenWFE
126
135
  #
127
136
  # no need for a timeout
128
137
 
129
- @timeout_job_id =
130
- scheduler.schedule_at(@timeout_at, self, :do_timeout!)
138
+ @timeout_job_id = "timeout_#{self.fei.to_s}"
139
+
140
+ scheduler.schedule_at(
141
+ @timeout_at,
142
+ { :schedulable => self,
143
+ :job_id => @timeout_job_id,
144
+ :do_timeout! => true })
131
145
 
132
146
  ldebug do
133
- "to_reschedule() will timeout at "+
134
- "#{OpenWFE::to_iso8601_date(@timeout_at)}"
147
+ "to_reschedule() will timeout at " +
148
+ "#{OpenWFE::to_iso8601_date(@timeout_at)}" +
149
+ " @timeout_job_id is #{@timeout_job_id}" +
150
+ " (oid #{object_id})"
135
151
  end
136
152
 
137
153
  #store_itself()
@@ -146,7 +162,8 @@ module OpenWFE
146
162
 
147
163
  ldebug do
148
164
  "unschedule_timeout() " +
149
- "@timeout_job_id is #{@timeout_job_id}"
165
+ "@timeout_job_id is #{@timeout_job_id}" +
166
+ " (oid #{object_id})"
150
167
  end
151
168
 
152
169
  #ldebug_callstack "unschedule_timeout()"
@@ -44,7 +44,13 @@
44
44
  module OpenWFE
45
45
 
46
46
  #
47
- # FlowExpressionId
47
+ # A FlowExpressionId is a unique identifier for a FlowExpression (an atomic
48
+ # piece of a process instance).
49
+ #
50
+ # As workitems do transit among the expressions and are emitted outside
51
+ # of the business process engine via 'participant expressions', workitems
52
+ # out there are identified via the FlowExpressionId of the participant
53
+ # expression that pushed them out (and is waiting for them to come back).
48
54
  #
49
55
  class FlowExpressionId
50
56
 
@@ -139,11 +145,6 @@ module OpenWFE
139
145
 
140
146
  alias eql? ==
141
147
 
142
- #alias to_debug_s to_s
143
- #def to_debug_s
144
- # "#{to_s} (h#{hash}) (i#{object_id})"
145
- #end
146
-
147
148
  def to_debug_s
148
149
  "(fei #{@workflow_definition_name} #{@workflow_definition_revision} #{@workflow_instance_id} #{@expression_id} #{@expression_name})"
149
150
  end
@@ -129,7 +129,7 @@ module OpenWFE
129
129
  #
130
130
  # seems like XML
131
131
 
132
- OpenWFE.xml_decode(data)
132
+ OpenWFE::XmlCodec::decode(data)
133
133
 
134
134
  elsif data[0, 3] == "---"
135
135
  #
@@ -47,7 +47,102 @@ require 'openwfe/participants/participant'
47
47
  module OpenWFE
48
48
 
49
49
  #
50
- # This participant is used to send an email notification
50
+ # MailParticipant is a simplification of EmailNotificationParticipant.
51
+ #
52
+ # It's initialized in this way :
53
+ #
54
+ # p = MailParticipant.new(
55
+ # :smtp_server => "mailhost.ourcompany.co.jp",
56
+ # :from_address => "bpms@our.ourcompany.co.jp",
57
+ # :template => "Dear ${f:name}, you've got mail")
58
+ #
59
+ # or
60
+ #
61
+ # p = MailParticipant.new(
62
+ # :smtp_server => "mailhost.ourcompany.co.jp",
63
+ # :smtp_port => 25,
64
+ # :from_address => "bpms@our.ourcompany.co.jp"
65
+ # ) do |workitem|
66
+ # s = ""
67
+ # s << "Dear #{workitem.name},\n"
68
+ # s << "\n"
69
+ # s << "it's #{Time.new.to_s} and you've got mail"
70
+ # s
71
+ # end
72
+ #
73
+ # When passing the mail template as a block, you have
74
+ # four possible arities :
75
+ # { |workitem| ... }
76
+ # { |participant_expression, workitem| ... }
77
+ # { |participant_expression, participant_instance, workitem| ... }
78
+ # { ... }
79
+ #
80
+ # The smtp server and host default to "127.0.0.1" / 25.
81
+ #
82
+ class MailParticipant
83
+ include LocalParticipant
84
+
85
+ def initialize (params, &block)
86
+
87
+ @smtp_server = params[:smtp_server]
88
+ @smtp_port = params[:smtp_port]
89
+ @from_address = params[:from_address]
90
+ @template = params[:template]
91
+
92
+ @block_template = block
93
+
94
+ # some defaults
95
+
96
+ @smtp_server = "127.0.0.1" unless @smtp_server
97
+ @smtp_port = 25 unless @smtp_port
98
+ end
99
+
100
+ #
101
+ # The method called each time a workitem reaches this participant
102
+ #
103
+ def consume (workitem)
104
+
105
+ fe = get_flow_expression(workitem)
106
+ to_address = workitem.email_target
107
+
108
+ #
109
+ # 1. Expand variables
110
+
111
+ msg = if @block_template
112
+ #@block_template.call(fe, self, workitem)
113
+ call_block @block_template, workitem
114
+ elsif @template
115
+ template = if @template.kind_of? File
116
+ @template.readlines
117
+ else
118
+ @template.to_s
119
+ end
120
+ OpenWFE::dosub(template, fe, workitem)
121
+ else
122
+ "(no template given)"
123
+ end
124
+
125
+ puts "msg >>>\n#{msg}<<<"
126
+
127
+ #
128
+ # 2. Send message
129
+
130
+ Net::SMTP.start(@smtp_server, @smtp_port) do |smtp|
131
+ smtp.send_message(msg, @from_address, to_address)
132
+ end
133
+
134
+ #
135
+ # 3. Reply to engine
136
+
137
+ reply_to_engine(workitem)
138
+ end
139
+ end
140
+
141
+ #
142
+ # This participant is used to send an email notification.
143
+ #
144
+ # It's perhaps better to use MailParticipant which is simpler to
145
+ # initialiaze. This class is anyway an extension of MailParticipant.
51
146
  #
52
147
  # @engine.register_participant(
53
148
  # 'eno',
@@ -113,8 +208,7 @@ module OpenWFE
113
208
  # Note that the template integrates the subject and requires then a double
114
209
  # newline before the message body.
115
210
  #
116
- class EmailNotificationParticipant
117
- include LocalParticipant
211
+ class EmailNotificationParticipant < MailParticipant
118
212
 
119
213
  #
120
214
  # Create a new email notification participant. Requires
@@ -123,52 +217,14 @@ module OpenWFE
123
217
  def initialize (
124
218
  smtp_server, smtp_port, from_address, template=nil, &block)
125
219
 
126
- @smtp_server = smtp_server
127
- @smtp_port = smtp_port
128
- @from_address = from_address
129
- @template = template
220
+ params = {}
221
+ params[:smtp_server] = smtp_server
222
+ params[:smtp_port] = smtp_port
223
+ params[:from_address] = from_address
130
224
 
131
- @block_template = block
132
- end
225
+ params[:template] = template if template
133
226
 
134
- #
135
- # The method called each time a workitem reaches this participant
136
- #
137
- def consume (workitem)
138
-
139
- fe = get_flow_expression(workitem)
140
- to_address = workitem.email_target
141
-
142
- #
143
- # 1. Expand variables
144
-
145
- msg = if @block_template
146
- @block_template.call(fe, self, workitem)
147
- elsif @template
148
- template = if @template.kind_of? File
149
- @template.readlines
150
- else
151
- @template.to_s
152
- end
153
- OpenWFE::dosub(template, fe, workitem)
154
- else
155
- "(no template given)"
156
- end
157
-
158
- puts "msg >>>\n#{msg}<<<"
159
-
160
- #
161
- # 2. Send message
162
-
163
- Net::SMTP.start(@smtp_server, @smtp_port) do |smtp|
164
- smtp.send_message(msg, @from_address, to_address)
165
- end
166
-
167
- #
168
- # 3. Reply to engine
169
-
170
- reply_to_engine(workitem)
227
+ super(params, &block)
171
228
  end
172
-
173
229
  end
174
230
  end
@@ -65,11 +65,12 @@ module OpenWFE
65
65
  "is missing in class '#{self.class}'")
66
66
  end
67
67
 
68
- #
68
+ #--
69
69
  # (optional)
70
70
  #
71
71
  #def cancel (cancelitem)
72
72
  #end
73
+ #++
73
74
  end
74
75
 
75
76
  #
@@ -88,8 +89,33 @@ module OpenWFE
88
89
 
89
90
  return nil if not @application_context
90
91
 
91
- @application_context[S_EXPRESSION_POOL]\
92
- .fetch_expression(workitem.flow_expression_id)
92
+ get_expression_pool.fetch_expression(workitem.flow_expression_id)
93
+ end
94
+
95
+ #
96
+ # A convenience method for calling block passed to participants
97
+ # for templates (mail participants) or execution (BlockParticipant).
98
+ #
99
+ # Allows for such blocks :
100
+ #
101
+ # { |workitem| ... }
102
+ # { |participant_expression, workitem| ... }
103
+ # { |participant_expression, participant, workitem| ... }
104
+ #
105
+ # For 0 or more than 3 arguments, the block will be called without
106
+ # arguments.
107
+ #
108
+ def call_block (block, workitem)
109
+
110
+ if block.arity == 1
111
+ block.call workitem
112
+ elsif block.arity == 2
113
+ block.call get_flow_expression(workitem), workitem
114
+ elsif block.arity == 3
115
+ block.call get_flow_expression(workitem), self, workitem
116
+ else
117
+ block.call
118
+ end
93
119
  end
94
120
 
95
121
  #
@@ -137,7 +137,7 @@ module OpenWFE
137
137
  @participants.each do |tuple|
138
138
  return tuple[1] if tuple[0].match(participant_name)
139
139
  end
140
- return nil
140
+ nil
141
141
  end
142
142
 
143
143
  #
@@ -153,7 +153,8 @@ module OpenWFE
153
153
  end
154
154
  end
155
155
  @participants.delete(pos) if pos > -1
156
- return pos > -1
156
+
157
+ pos > -1
157
158
  end
158
159
 
159
160
  #
@@ -187,6 +188,13 @@ module OpenWFE
187
188
 
188
189
  onotify :dispatch, :after_consume, workitem
189
190
  end
191
+
192
+ #
193
+ # The method onotify (from Osbservable) is made public so that
194
+ # ParticipantExpression instances may notify the pmap of applies
195
+ # and replies.
196
+ #
197
+ public :onotify
190
198
  end
191
199
 
192
200
  end
@@ -68,14 +68,6 @@ module OpenWFE
68
68
  #
69
69
  def initialize (context_or_dir=nil)
70
70
 
71
- #if context_or_dir.kind_of? Hash
72
- # @application_context = context_or_dir
73
- # @workdir = @application_context[:work_directory]
74
- #else
75
- # @workdir = context_or_dir
76
- #end
77
- #@workdir = OpenWFE::DEFAULT_WORK_DIRECTORY unless @workdir
78
- #@workdir = "#{@workdir}/out/"
79
71
  @workdir = OpenWFE::get_work_directory(context_or_dir) + "/out/"
80
72
 
81
73
  @reply_anyway = false
@@ -177,18 +169,9 @@ module OpenWFE
177
169
 
178
170
  def consume (workitem)
179
171
 
180
- result = if @block.arity == 1
181
- @block.call workitem
182
- elsif @block.arity > 1
183
- @block.call get_flow_expression(workitem), workitem
184
- else
185
- @block.call
186
- end
172
+ result = call_block @block, workitem
187
173
 
188
- if result
189
- #ldebug { "consume() result is of class #{result.class.name}" }
190
- workitem.set_result(result)
191
- end
174
+ workitem.set_result(result) if result
192
175
 
193
176
  reply_to_engine(workitem) \
194
177
  if workitem.kind_of? InFlowWorkItem
@@ -196,6 +179,35 @@ module OpenWFE
196
179
  end
197
180
  end
198
181
 
182
+ #
183
+ # The NullParticipant never replies, it simply discards the workitems
184
+ # it receives.
185
+ #
186
+ class NullParticipant
187
+ include LocalParticipant
188
+
189
+ #
190
+ # Simply discards the incoming workitem
191
+ #
192
+ def consume (workitem)
193
+ end
194
+ end
195
+
196
+ #
197
+ # The NoOperationParticipant immediately replies to the engine upon
198
+ # receiving a workitem.
199
+ #
200
+ class NoOperationParticipant
201
+ include LocalParticipant
202
+
203
+ #
204
+ # Simply discards the incoming workitem
205
+ #
206
+ def consume (workitem)
207
+ reply_to_engine workitem
208
+ end
209
+ end
210
+
199
211
  #
200
212
  # The PrintParticipant will just emit its name to the
201
213
  # test tracer if any or to stdout else.
@@ -94,6 +94,8 @@ module OpenWFE
94
94
  socket.puts
95
95
  socket.close_write
96
96
 
97
+ #print "\n__socket.closed? #{socket.closed?}"
98
+
97
99
  reply = fetch_reply(socket)
98
100
 
99
101
  socket.close
@@ -190,7 +192,7 @@ module OpenWFE
190
192
  #
191
193
  def encode_workitem (wi)
192
194
 
193
- sxml = OpenWFE::xml_encode(wi)
195
+ sxml = OpenWFE::XmlCodec::encode(wi)
194
196
 
195
197
  s = "xmlCoder #{sxml.length}\n"
196
198
  s << "\n"