ruote 2.1.11 → 2.2.0

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 (217) hide show
  1. data/CHANGELOG.txt +60 -0
  2. data/CREDITS.txt +22 -4
  3. data/LICENSE.txt +1 -1
  4. data/README.rdoc +6 -7
  5. data/Rakefile +58 -59
  6. data/TODO.txt +137 -65
  7. data/couch_url.txt +1 -0
  8. data/jruby_issue.txt +32 -0
  9. data/lib/ruote.rb +1 -1
  10. data/lib/ruote/context.rb +12 -10
  11. data/lib/ruote/engine.rb +280 -145
  12. data/lib/ruote/engine/process_error.rb +5 -5
  13. data/lib/ruote/engine/process_status.rb +47 -28
  14. data/lib/ruote/exp/command.rb +7 -10
  15. data/lib/ruote/exp/commanded.rb +2 -2
  16. data/lib/ruote/exp/condition.rb +130 -43
  17. data/lib/ruote/exp/fe_add_branches.rb +2 -2
  18. data/lib/ruote/exp/fe_apply.rb +1 -1
  19. data/lib/ruote/exp/fe_cancel_process.rb +3 -3
  20. data/lib/ruote/exp/fe_command.rb +3 -3
  21. data/lib/ruote/exp/fe_concurrence.rb +4 -4
  22. data/lib/ruote/exp/fe_concurrent_iterator.rb +17 -5
  23. data/lib/ruote/exp/fe_cron.rb +3 -3
  24. data/lib/ruote/exp/fe_cursor.rb +5 -5
  25. data/lib/ruote/exp/fe_define.rb +3 -3
  26. data/lib/ruote/exp/fe_echo.rb +3 -3
  27. data/lib/ruote/exp/fe_equals.rb +2 -2
  28. data/lib/ruote/exp/fe_error.rb +2 -2
  29. data/lib/ruote/exp/fe_filter.rb +519 -0
  30. data/lib/ruote/exp/fe_forget.rb +9 -2
  31. data/lib/ruote/exp/fe_given.rb +154 -0
  32. data/lib/ruote/exp/fe_if.rb +16 -13
  33. data/lib/ruote/exp/fe_inc.rb +3 -3
  34. data/lib/ruote/exp/fe_iterator.rb +4 -4
  35. data/lib/ruote/exp/fe_let.rb +75 -0
  36. data/lib/ruote/exp/fe_listen.rb +68 -12
  37. data/lib/ruote/exp/fe_lose.rb +110 -0
  38. data/lib/ruote/exp/fe_noop.rb +1 -1
  39. data/lib/ruote/exp/{fe_when.rb → fe_once.rb} +25 -21
  40. data/lib/ruote/exp/fe_participant.rb +14 -17
  41. data/lib/ruote/exp/fe_redo.rb +10 -6
  42. data/lib/ruote/exp/fe_ref.rb +1 -1
  43. data/lib/ruote/exp/fe_registerp.rb +112 -0
  44. data/lib/ruote/exp/fe_reserve.rb +3 -3
  45. data/lib/ruote/exp/fe_restore.rb +2 -2
  46. data/lib/ruote/exp/fe_save.rb +2 -2
  47. data/lib/ruote/exp/fe_sequence.rb +3 -4
  48. data/lib/ruote/exp/fe_set.rb +16 -7
  49. data/lib/ruote/exp/fe_subprocess.rb +23 -1
  50. data/lib/ruote/exp/fe_that.rb +92 -0
  51. data/lib/ruote/exp/fe_undo.rb +3 -3
  52. data/lib/ruote/exp/fe_unregisterp.rb +71 -0
  53. data/lib/ruote/exp/fe_wait.rb +2 -2
  54. data/lib/ruote/exp/flowexpression.rb +153 -78
  55. data/lib/ruote/exp/iterator.rb +2 -2
  56. data/lib/ruote/exp/merge.rb +2 -2
  57. data/lib/ruote/exp/ro_attributes.rb +14 -12
  58. data/lib/ruote/exp/ro_filters.rb +136 -0
  59. data/lib/ruote/exp/ro_persist.rb +51 -35
  60. data/lib/ruote/exp/ro_variables.rb +18 -27
  61. data/lib/ruote/fei.rb +73 -33
  62. data/lib/ruote/id/mnemo_wfid_generator.rb +1 -1
  63. data/lib/ruote/id/wfid_generator.rb +11 -4
  64. data/lib/ruote/log/default_history.rb +122 -0
  65. data/lib/ruote/log/pretty.rb +36 -8
  66. data/lib/ruote/log/storage_history.rb +37 -5
  67. data/lib/ruote/log/test_logger.rb +26 -24
  68. data/lib/ruote/log/wait_logger.rb +5 -3
  69. data/lib/ruote/part/block_participant.rb +22 -11
  70. data/lib/ruote/part/engine_participant.rb +6 -7
  71. data/lib/ruote/part/local_participant.rb +6 -12
  72. data/lib/ruote/part/no_op_participant.rb +4 -4
  73. data/lib/ruote/part/null_participant.rb +4 -4
  74. data/lib/ruote/part/smtp_participant.rb +4 -4
  75. data/lib/ruote/part/storage_participant.rb +40 -20
  76. data/lib/ruote/part/template.rb +4 -4
  77. data/lib/ruote/participant.rb +0 -1
  78. data/lib/ruote/{parser.rb → reader.rb} +30 -25
  79. data/lib/ruote/{parser → reader}/ruby_dsl.rb +28 -11
  80. data/lib/ruote/{parser → reader}/xml.rb +6 -5
  81. data/lib/ruote/receiver/base.rb +35 -13
  82. data/lib/ruote/storage/base.rb +20 -18
  83. data/lib/ruote/storage/composite_storage.rb +10 -10
  84. data/lib/ruote/storage/fs_storage.rb +17 -10
  85. data/lib/ruote/storage/hash_storage.rb +29 -18
  86. data/lib/ruote/svc/dispatch_pool.rb +41 -14
  87. data/lib/ruote/svc/dollar_sub.rb +50 -17
  88. data/lib/ruote/svc/error_handler.rb +19 -11
  89. data/lib/ruote/svc/expression_map.rb +4 -4
  90. data/lib/ruote/svc/participant_list.rb +105 -100
  91. data/lib/ruote/svc/tracker.rb +58 -18
  92. data/lib/ruote/svc/treechecker.rb +51 -24
  93. data/lib/ruote/tree_dot.rb +4 -4
  94. data/lib/ruote/util/filter.rb +440 -0
  95. data/lib/ruote/util/hashdot.rb +4 -4
  96. data/lib/ruote/util/look.rb +2 -6
  97. data/lib/ruote/util/lookup.rb +9 -7
  98. data/lib/ruote/util/misc.rb +40 -8
  99. data/lib/ruote/util/ometa.rb +1 -1
  100. data/lib/ruote/util/serializer.rb +4 -4
  101. data/lib/ruote/util/subprocess.rb +29 -9
  102. data/lib/ruote/util/time.rb +4 -4
  103. data/lib/ruote/util/tree.rb +3 -3
  104. data/lib/ruote/version.rb +2 -2
  105. data/lib/ruote/worker.rb +55 -32
  106. data/lib/ruote/workitem.rb +64 -11
  107. data/ruote.gemspec +31 -302
  108. data/test/bm/launch_bench.rb +37 -0
  109. data/test/functional/base.rb +60 -18
  110. data/test/functional/concurrent_base.rb +2 -2
  111. data/test/functional/ct_0_concurrence.rb +1 -1
  112. data/test/functional/ct_1_iterator.rb +1 -1
  113. data/test/functional/ct_2_cancel.rb +1 -1
  114. data/test/functional/eft_0_process_definition.rb +2 -2
  115. data/test/functional/eft_10_cancel_process.rb +1 -1
  116. data/test/functional/eft_11_wait.rb +19 -11
  117. data/test/functional/eft_12_listen.rb +79 -13
  118. data/test/functional/eft_13_iterator.rb +13 -10
  119. data/test/functional/eft_14_cursor.rb +98 -9
  120. data/test/functional/eft_15_loop.rb +6 -4
  121. data/test/functional/eft_16_if.rb +12 -0
  122. data/test/functional/eft_18_concurrent_iterator.rb +31 -32
  123. data/test/functional/eft_19_reserve.rb +4 -4
  124. data/test/functional/eft_1_echo.rb +9 -0
  125. data/test/functional/eft_20_save.rb +4 -4
  126. data/test/functional/{eft_28_when.rb → eft_28_once.rb} +33 -7
  127. data/test/functional/eft_30_ref.rb +17 -2
  128. data/test/functional/eft_31_registerp.rb +130 -0
  129. data/test/functional/eft_32_lose.rb +93 -0
  130. data/test/functional/eft_33_let.rb +31 -0
  131. data/test/functional/eft_34_given.rb +123 -0
  132. data/test/functional/eft_35_filter.rb +269 -0
  133. data/test/functional/eft_3_participant.rb +4 -6
  134. data/test/functional/eft_4_set.rb +16 -2
  135. data/test/functional/eft_5_subprocess.rb +2 -4
  136. data/test/functional/eft_6_concurrence.rb +29 -29
  137. data/test/functional/eft_8_undo.rb +39 -3
  138. data/test/functional/eft_9_redo.rb +94 -2
  139. data/test/functional/ft_10_dollar.rb +81 -2
  140. data/test/functional/ft_11_recursion.rb +13 -17
  141. data/test/functional/ft_12_launchitem.rb +9 -5
  142. data/test/functional/ft_13_variables.rb +7 -9
  143. data/test/functional/ft_14_re_apply.rb +6 -9
  144. data/test/functional/ft_15_timeout.rb +18 -18
  145. data/test/functional/ft_16_participant_params.rb +1 -3
  146. data/test/functional/ft_17_conditional.rb +25 -2
  147. data/test/functional/ft_18_kill.rb +65 -12
  148. data/test/functional/ft_1_process_status.rb +147 -71
  149. data/test/functional/ft_20_storage_participant.rb +0 -1
  150. data/test/functional/ft_21_forget.rb +82 -1
  151. data/test/functional/{ft_24_block_participants.rb → ft_24_block_participant.rb} +42 -11
  152. data/test/functional/ft_25_receiver.rb +47 -17
  153. data/test/functional/{ft_26_participant_timeout.rb → ft_26_participant_rtimeout.rb} +56 -19
  154. data/test/functional/ft_29_part_template.rb +6 -5
  155. data/test/functional/ft_2_errors.rb +21 -37
  156. data/test/functional/ft_30_smtp_participant.rb +1 -1
  157. data/test/functional/ft_31_part_blocking.rb +8 -6
  158. data/test/functional/ft_34_cursor_rewind.rb +13 -10
  159. data/test/functional/ft_35_add_service.rb +1 -1
  160. data/test/functional/ft_36_storage_history.rb +24 -1
  161. data/test/functional/ft_37_default_history.rb +109 -0
  162. data/test/functional/ft_38_participant_more.rb +10 -10
  163. data/test/functional/ft_39_wait_for.rb +12 -9
  164. data/test/functional/ft_3_participant_registration.rb +111 -32
  165. data/test/functional/ft_40_wait_logger.rb +2 -1
  166. data/test/functional/ft_41_participants.rb +30 -4
  167. data/test/functional/ft_43_participant_on_reply.rb +6 -23
  168. data/test/functional/ft_45_participant_accept.rb +4 -4
  169. data/test/functional/ft_46_launch_single.rb +36 -2
  170. data/test/functional/ft_47_wfid_generator.rb +54 -0
  171. data/test/functional/ft_48_lose.rb +112 -0
  172. data/test/functional/ft_49_engine_on_error.rb +201 -0
  173. data/test/functional/ft_4_cancel.rb +66 -6
  174. data/test/functional/ft_50_engine_config.rb +22 -0
  175. data/test/functional/ft_51_misc.rb +67 -0
  176. data/test/functional/ft_52_case.rb +134 -0
  177. data/test/functional/ft_53_engine_on_terminate.rb +95 -0
  178. data/test/functional/ft_54_patterns.rb +104 -0
  179. data/test/functional/{ft_37_engine_participant.rb → ft_55_engine_participant.rb} +4 -5
  180. data/test/functional/ft_56_filter_attribute.rb +259 -0
  181. data/test/functional/ft_5_on_error.rb +77 -30
  182. data/test/functional/ft_6_on_cancel.rb +66 -11
  183. data/test/functional/ft_7_tags.rb +94 -5
  184. data/test/functional/ft_8_participant_consumption.rb +36 -5
  185. data/test/functional/ft_9_subprocesses.rb +10 -10
  186. data/test/functional/rt_1_listen.rb +3 -3
  187. data/test/functional/{rt_3_when.rb → rt_3_once.rb} +4 -4
  188. data/test/functional/storage_helper.rb +15 -13
  189. data/test/functional/test.rb +1 -3
  190. data/test/test_helper.rb +0 -8
  191. data/test/unit/storage.rb +154 -10
  192. data/test/unit/{ut_0_ruby_parser.rb → ut_0_ruby_reader.rb} +61 -11
  193. data/test/unit/ut_11_lookup.rb +7 -0
  194. data/test/unit/ut_13_serializer.rb +1 -1
  195. data/test/unit/ut_15_util.rb +23 -0
  196. data/test/unit/{ut_16_parser.rb → ut_16_reader.rb} +11 -13
  197. data/test/unit/ut_1_fei.rb +57 -10
  198. data/test/unit/ut_20_composite_storage.rb +25 -11
  199. data/test/unit/ut_21_participant_list.rb +47 -0
  200. data/test/unit/ut_22_filter.rb +903 -0
  201. data/test/unit/ut_3_wait_logger.rb +2 -6
  202. data/test/unit/ut_6_condition.rb +164 -17
  203. data/test/unit/ut_7_workitem.rb +28 -0
  204. data/test/unit/ut_8_tree_to_dot.rb +1 -1
  205. data/test/unit/{ut_9_xml_parser.rb → ut_9_xml_reader.rb} +5 -5
  206. metadata +108 -84
  207. data/.gitignore +0 -4
  208. data/examples/barley.rb +0 -391
  209. data/examples/flickr_report.rb +0 -107
  210. data/examples/pong.rb +0 -37
  211. data/examples/ruote_quickstart.rb +0 -43
  212. data/examples/web_first_page.rb +0 -68
  213. data/lib/ruote/part/hash_participant.rb +0 -91
  214. data/test/README.rdoc +0 -15
  215. data/test/functional/crunner.sh +0 -19
  216. data/test/pdef.xml +0 -7
  217. data/test/unit/ut_2_wfidgen.rb +0 -21
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2010, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -63,7 +63,7 @@ module Ruote
63
63
  # Will load any expression in the Ruote::Exp:: namespace and map
64
64
  # its names to its class.
65
65
  #
66
- def initialize (worker)
66
+ def initialize(worker)
67
67
 
68
68
  @map = {}
69
69
 
@@ -81,14 +81,14 @@ module Ruote
81
81
 
82
82
  # Returns the expression class for the given expression name
83
83
  #
84
- def expression_class (exp_name)
84
+ def expression_class(exp_name)
85
85
 
86
86
  @map[exp_name]
87
87
  end
88
88
 
89
89
  protected
90
90
 
91
- def add (exp_class)
91
+ def add(exp_class)
92
92
 
93
93
  exp_class.expression_names.each { |n| @map[n] = exp_class }
94
94
  end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2010, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
23
23
  #++
24
24
 
25
25
 
26
+ require 'sourcify'
26
27
  require 'ruote/part/block_participant'
27
28
 
28
29
 
@@ -37,33 +38,35 @@ module Ruote
37
38
  #
38
39
  class ParticipantList
39
40
 
40
- attr_reader :instantiated_participants
41
-
42
- def initialize (context)
41
+ def initialize(context)
43
42
 
44
43
  @context = context
45
- @instantiated_participants = {}
46
44
  end
47
45
 
48
46
  # Registers a participant. Called by Engine#register_participant.
49
47
  #
50
- def register (name, participant, options, block)
48
+ def register(name, participant, options, block)
49
+
50
+ raise(
51
+ ArgumentError.new(
52
+ "can only accept strings (classnames) or classes as participant arg")
53
+ ) unless [ String, Class, NilClass ].include?(participant.class)
54
+
55
+ klass = (participant || Ruote::BlockParticipant).to_s
51
56
 
52
57
  options = options.inject({}) { |h, (k, v)|
53
58
  h[k.to_s] = v.is_a?(Symbol) ? v.to_s : v
54
59
  h
55
60
  }
56
61
 
57
- entry = if participant.is_a?(Class) || participant.is_a?(String)
58
- [ participant.to_s, options ]
59
- else
60
- "inpa_#{name.inspect}"
61
- # INstantiated PArticipant
62
+ if block
63
+ options['block'] = block.to_source
64
+ @context.treechecker.block_check(options['block'])
62
65
  end
63
66
 
64
67
  key = (name.is_a?(Regexp) ? name : Regexp.new("^#{name}$")).source
65
68
 
66
- entry = [ key, entry ]
69
+ entry = [ key, [ klass, options ] ]
67
70
 
68
71
  list = get_list
69
72
 
@@ -82,23 +85,12 @@ module Ruote
82
85
  # if put returns something it means the put failed, have to redo the
83
86
  # work...
84
87
  #
85
- return register(name, participant, options, block, r)
88
+ return register(name, participant, options, block)
86
89
  end
87
90
 
88
- if entry.last.is_a?(String)
89
-
90
- participant = BlockParticipant.new(block, options) if block
91
-
92
- participant.context = @context if participant.respond_to?(:context=)
93
- @instantiated_participants[entry.last] = participant
94
- #participant
95
-
91
+ if entry.last.first == 'Ruote::StorageParticipant'
92
+ Ruote::StorageParticipant.new(@context)
96
93
  else
97
-
98
- if entry.last.first == 'Ruote::StorageParticipant'
99
- return Ruote::StorageParticipant.new(@context)
100
- end
101
-
102
94
  nil
103
95
  end
104
96
  end
@@ -108,37 +100,19 @@ module Ruote
108
100
  #
109
101
  # Called usually by Engine#unregister_participant.
110
102
  #
111
- def unregister (name_or_participant)
103
+ def unregister(name_or_participant)
112
104
 
113
105
  code = nil
114
106
  entry = nil
115
107
  list = get_list
116
108
 
117
- if name_or_participant.is_a?(Symbol)
118
- name_or_participant = name_or_participant.to_s
119
- end
120
-
121
- if name_or_participant.is_a?(String)
122
-
123
- entry = list['list'].find { |re, pa| name_or_participant.match(re) }
124
-
125
- return nil unless entry
109
+ name_or_participant = name_or_participant.to_s
126
110
 
127
- code = entry.last if entry.last.is_a?(String)
111
+ entry = list['list'].find { |re, pa| name_or_participant.match(re) }
128
112
 
129
- else # we've been given a participant instance
113
+ return nil unless entry
130
114
 
131
- code = @instantiated_participants.find { |k, v|
132
- v == name_or_participant
133
- }
134
-
135
- return nil unless code
136
-
137
- code = code.first
138
-
139
- entry = list['list'].find { |re, pa| pa == code }
140
-
141
- end
115
+ code = entry.last if entry.last.is_a?(String)
142
116
 
143
117
  list['list'].delete(entry)
144
118
 
@@ -146,11 +120,9 @@ module Ruote
146
120
  #
147
121
  # put failed, have to redo it
148
122
  #
149
- return unregister(name_or_participant, r)
123
+ return unregister(name_or_participant)
150
124
  end
151
125
 
152
- @instantiated_participants.delete(code) if code
153
-
154
126
  entry.first
155
127
  end
156
128
 
@@ -159,15 +131,13 @@ module Ruote
159
131
  #
160
132
  # Mostly a combination of #lookup_info and #instantiate.
161
133
  #
162
- def lookup (participant_name, workitem, opts={})
134
+ def lookup(participant_name, workitem, opts={})
163
135
 
164
- pinfo = participant_name
136
+ pinfo = participant_name.is_a?(String) ?
137
+ lookup_info(participant_name, workitem) : participant_name
165
138
 
166
- if participant_name.is_a?(String) && participant_name[0, 5] != 'inpa_'
167
- pinfo = lookup_info(participant_name, workitem)
168
- end
169
-
170
- pinfo ? instantiate(pinfo, opts) : nil
139
+ pinfo ?
140
+ instantiate(pinfo, opts) : nil
171
141
  end
172
142
 
173
143
  # Given a participant name, returns
@@ -175,15 +145,17 @@ module Ruote
175
145
  # Returns nil if there is no participant registered that covers the given
176
146
  # participant name.
177
147
  #
178
- def lookup_info (pname, workitem)
148
+ def lookup_info(pname, workitem)
179
149
 
180
150
  get_list['list'].each do |regex, pinfo|
181
151
 
182
152
  next unless pname.match(regex)
183
153
 
154
+ return pinfo if workitem.nil?
155
+
184
156
  pa = instantiate(pinfo, :if_respond_to? => :accept?)
185
157
 
186
- return pinfo unless pa
158
+ return pinfo if pa.nil?
187
159
 
188
160
  return pinfo if pa.accept?(
189
161
  Ruote::Workitem.new(workitem.merge('participant_name' => pname))
@@ -195,18 +167,14 @@ module Ruote
195
167
 
196
168
  # Returns an instance of a participant
197
169
  #
198
- def instantiate (pinfo, opts={})
170
+ def instantiate(pinfo, opts={})
199
171
 
200
- irt = opts[:if_respond_to?]
201
-
202
- pinfo = @instantiated_participants[pinfo] if pinfo.is_a?(String)
203
-
204
- if pinfo.respond_to?(:consume)
205
- return (pinfo.respond_to?(irt) ? pinfo : nil) if irt
206
- return pinfo
207
- end
208
-
209
- return nil unless pinfo
172
+ #pinfo = @instantiated_participants[pinfo] if pinfo.is_a?(String)
173
+ #if pinfo.respond_to?(:consume)
174
+ # return (pinfo.respond_to?(irt) ? pinfo : nil) if irt
175
+ # return pinfo
176
+ #end
177
+ #return nil unless pinfo
210
178
 
211
179
  pa_class_name, options = pinfo
212
180
 
@@ -220,18 +188,26 @@ module Ruote
220
188
  pa_class = Ruote.constantize(pa_class_name)
221
189
  pa_m = pa_class.instance_methods
222
190
 
191
+ irt = opts[:if_respond_to?]
192
+
223
193
  if irt && ! (pa_m.include?(irt.to_s) || pa_m.include?(irt.to_sym))
224
194
  return nil
225
195
  end
226
196
 
227
- pa = if pa_class.instance_method(:initialize).arity > 0
228
- pa_class.new(options)
197
+ initialize_participant(pa_class, options)
198
+ end
199
+
200
+ def initialize_participant(klass, options)
201
+
202
+ participant = if klass.instance_method(:initialize).arity == 0
203
+ klass.new
229
204
  else
230
- pa_class.new
205
+ klass.new(options)
231
206
  end
232
- pa.context = @context if pa.respond_to?(:context=)
233
207
 
234
- pa
208
+ participant.context = @context if participant.respond_to?(:context=)
209
+
210
+ participant
235
211
  end
236
212
 
237
213
  # Return a list of names (regex) for the registered participants
@@ -241,14 +217,18 @@ module Ruote
241
217
  get_list['list'].collect { |re, pa| re }
242
218
  end
243
219
 
244
- # Shuts down the 'instantiated participants' (engine worker participants)
245
- # if they respond to #shutdown.
220
+ # Calls #shutdown on any participant that sports this method.
246
221
  #
247
222
  def shutdown
248
223
 
249
- @instantiated_participants.each { |re, pa|
250
- pa.shutdown if pa.respond_to?(:shutdown)
251
- }
224
+ get_list['list'].each do |re, (kl, op)|
225
+
226
+ kl = (Ruote.constantize(kl) rescue nil)
227
+
228
+ if (kl.instance_method(:shutdown) rescue false)
229
+ initialize_participant(kl, op).shutdown
230
+ end
231
+ end
252
232
  end
253
233
 
254
234
  # Used by Engine#participant_list
@@ -268,16 +248,21 @@ module Ruote
268
248
  #
269
249
  # See ParticipantList#list
270
250
  #
271
- def list= (pl)
251
+ def list=(pl)
272
252
 
273
253
  list = get_list
274
- list['list'] = pl.collect { |e| ParticipantEntry.read(e) }
254
+ list['list'] = pl.collect { |e|
255
+ ParticipantEntry.read(e)
256
+ }.collect { |e|
257
+ e[0] = e[0].source if e[0].is_a?(Regexp)
258
+ e
259
+ }
275
260
 
276
261
  if r = @context.storage.put(list)
277
262
  #
278
263
  # put failed, have to redo it
279
264
  #
280
- list= (pl)
265
+ list=(pl)
281
266
  end
282
267
  end
283
268
 
@@ -316,7 +301,7 @@ module Ruote
316
301
 
317
302
  attr_accessor :regex, :classname, :options
318
303
 
319
- def initialize (a)
304
+ def initialize(a)
320
305
  @regex = a.first
321
306
  if a.last.is_a?(Array)
322
307
  @classname = a.last.first
@@ -328,34 +313,54 @@ module Ruote
328
313
  end
329
314
 
330
315
  def to_a
331
- @classname[0, 5] == 'inpa_' ?
332
- [ @regex, @classname ] :
333
- [ @regex, [ @classname, @options ] ]
316
+
317
+ [ @regex, [ @classname, @options ] ]
334
318
  end
335
319
 
336
320
  def to_s
321
+
337
322
  "/#{@regex}/ ==> #{@classname} #{@options.inspect}"
338
323
  end
339
324
 
340
- def self.read (elt)
325
+ # Makes sense of whatever is given to it, returns something like
326
+ #
327
+ # [ regex, [ klass, opts ] ]
328
+ #
329
+ def self.read(elt)
341
330
 
342
- if elt.is_a?(ParticipantEntry)
343
- return elt.to_a
344
- end
331
+ return elt.to_a if elt.is_a?(ParticipantEntry)
345
332
 
346
333
  if elt.is_a?(Hash)
347
- return elt['classname'][0, 5] == 'inpa_' ?
348
- [ elt['regex'], elt['classname'] ] :
349
- [ elt['regex'], [ elt['classname'], elt['options'] ] ]
334
+
335
+ options = elt['options'] || elt.reject { |k, v|
336
+ %w[ name regex regexp class classname ].include?(k)
337
+ }
338
+
339
+ name = elt.find { |k, v| v == nil }
340
+ if name
341
+ name = name.first
342
+ elt.delete(name)
343
+ options.delete(name)
344
+ end
345
+ name = name || elt['name']
346
+ name = Ruote.regex_or_s(name)
347
+
348
+ regex = name
349
+ unless name
350
+ regex = Ruote.regex_or_s(elt['regex'] || elt['regexp'])
351
+ regex = regex.is_a?(String) ? Regexp.new(regex) : regex
352
+ end
353
+
354
+ klass = elt['classname'] || elt['class']
355
+
356
+ return [ regex, [ klass, options ] ]
350
357
  end
351
358
 
352
359
  # else elt is a Array
353
360
 
354
- if elt.size == 3
355
- return [ elt[0], [ elt[1], elt[2] ] ]
356
- end
361
+ return [ Ruote.regex_or_s(elt[0]), [ elt[1], elt[2] ] ] if elt.size == 3
357
362
 
358
- elt
363
+ [ Ruote.regex_or_s(elt[0]), elt[1] ]
359
364
  end
360
365
  end
361
366
  end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2010, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -34,7 +34,7 @@ module Ruote
34
34
  #
35
35
  class Tracker
36
36
 
37
- def initialize (context)
37
+ def initialize(context)
38
38
 
39
39
  @context = context
40
40
 
@@ -54,52 +54,83 @@ module Ruote
54
54
  # The worker passes all the messages it has to process to the tracker via
55
55
  # this method.
56
56
  #
57
- def notify (msg)
57
+ def notify(msg)
58
58
 
59
- doc = @context.storage.get_trackers
59
+ m_error = msg['error']
60
+ m_wfid = msg['wfid'] || (msg['fei']['wfid'] rescue nil)
61
+ m_action = msg['action']
62
+
63
+ @context.storage.get_trackers['trackers'].each do |tracker_id, tracker|
60
64
 
61
- doc['trackers'].values.each do |tracker|
65
+ # filter msgs
62
66
 
63
67
  t_wfid = tracker['wfid']
64
68
  t_action = tracker['action']
65
- m_wfid = msg['wfid'] || (msg['fei']['wfid'] rescue nil)
66
69
 
67
70
  next if t_wfid && t_wfid != m_wfid
68
- next if t_action && t_action != msg['action']
71
+ next if t_action && t_action != m_action
69
72
 
70
73
  next unless does_match?(msg, tracker['conditions'])
71
74
 
75
+ msg = msg['msg'] if m_action == 'error_intercepted'
76
+
77
+ if tracker_id == 'on_error' || tracker_id == 'on_terminate'
78
+
79
+ fields = msg['workitem']['fields']
80
+
81
+ next if m_action == 'error_intercepted' && fields['__error__']
82
+ next if m_action == 'terminated' && (fields['__error__'] || fields['__terminate__'])
83
+ end
84
+
85
+ # prepare and emit/put 'reaction' message
86
+
72
87
  m = tracker['msg']
73
88
 
74
- @context.storage.put_msg(
75
- m.delete('action'),
76
- m.merge!('workitem' => msg['workitem']))
89
+ action = m.delete('action')
90
+
91
+ m['wfid'] = m_wfid if m['wfid'] == 'replace'
92
+ m['wfid'] ||= @context.wfidgen.generate
93
+
94
+ m['workitem'] = msg['workitem'] if m['workitem'] == 'replace'
95
+
96
+ if tracker_id == 'on_error' && m_action == 'error_intercepted'
97
+ m['workitem']['fields']['__error__'] = m_error
98
+ elsif tracker_id == 'on_terminate' && m_action == 'terminated'
99
+ m['workitem']['fields']['__terminate__'] = { 'wfid' => m_wfid }
100
+ end
101
+
102
+ if m['variables'] == 'compile'
103
+ fexp = Ruote::Exp::FlowExpression.fetch(@context, msg['fei'])
104
+ m['variables'] = fexp ? fexp.compile_variables : {}
105
+ end
106
+
107
+ @context.storage.put_msg(action, m)
77
108
  end
78
109
  end
79
110
 
80
111
  # Adds a tracker (usually when a 'listen' expression gets applied).
81
112
  #
82
- def add_tracker (wfid, action, fei, conditions, msg, doc=nil)
113
+ def add_tracker(wfid, action, id, conditions, msg)
83
114
 
84
- doc ||= @context.storage.get_trackers
115
+ doc = @context.storage.get_trackers
85
116
 
86
- doc['trackers'][Ruote.to_storage_id(fei)] =
117
+ doc['trackers'][id] =
87
118
  { 'wfid' => wfid,
88
119
  'action' => action,
89
- 'fei' => fei,
120
+ 'id' => id,
90
121
  'conditions' => conditions,
91
122
  'msg' => msg }
92
123
 
93
124
  r = @context.storage.put(doc)
94
125
 
95
- add_tracker(wfid, action, fei, msg, r) if r
126
+ add_tracker(wfid, action, id, msg) if r
96
127
  # the put failed, have to redo the work
97
128
  end
98
129
 
99
130
  # Removes a tracker (usually when a 'listen' expression replies to its
100
131
  # parent expression or is cancelled).
101
132
  #
102
- def remove_tracker (fei, doc=nil)
133
+ def remove_tracker(fei, doc=nil)
103
134
 
104
135
  doc ||= @context.storage.get_trackers
105
136
 
@@ -113,11 +144,20 @@ module Ruote
113
144
 
114
145
  protected
115
146
 
116
- def does_match? (msg, conditions)
147
+ def does_match?(msg, conditions)
148
+
149
+ return true unless conditions
117
150
 
118
151
  conditions.each do |k, v|
152
+
119
153
  val = msg[k]
120
- return false unless val && val.match(v)
154
+ v = Ruote.regex_or_s(v)
155
+
156
+ if v.is_a?(String)
157
+ return false unless val && v == val
158
+ else
159
+ return false unless val && v.match(val)
160
+ end
121
161
  end
122
162
 
123
163
  true