ruote 2.1.11 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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