ruote 2.3.0.1 → 2.3.0.2

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 (148) hide show
  1. data/CHANGELOG.txt +23 -0
  2. data/CREDITS.txt +4 -0
  3. data/LICENSE.txt +1 -1
  4. data/lib/ruote.rb +2 -0
  5. data/lib/ruote/context.rb +2 -1
  6. data/lib/ruote/dashboard.rb +169 -13
  7. data/lib/ruote/dboard/mutation.rb +282 -0
  8. data/lib/ruote/dboard/process_error.rb +1 -1
  9. data/lib/ruote/dboard/process_status.rb +61 -48
  10. data/lib/ruote/engine.rb +1 -1
  11. data/lib/ruote/exp/command.rb +1 -1
  12. data/lib/ruote/exp/commanded.rb +1 -1
  13. data/lib/ruote/exp/condition.rb +2 -1
  14. data/lib/ruote/exp/fe_add_branches.rb +1 -1
  15. data/lib/ruote/exp/fe_apply.rb +1 -1
  16. data/lib/ruote/exp/fe_await.rb +97 -48
  17. data/lib/ruote/exp/fe_cancel_process.rb +1 -1
  18. data/lib/ruote/exp/fe_command.rb +2 -3
  19. data/lib/ruote/exp/fe_concurrence.rb +162 -66
  20. data/lib/ruote/exp/fe_concurrent_iterator.rb +25 -7
  21. data/lib/ruote/exp/fe_cron.rb +1 -1
  22. data/lib/ruote/exp/fe_cursor.rb +10 -11
  23. data/lib/ruote/exp/fe_define.rb +1 -1
  24. data/lib/ruote/exp/fe_echo.rb +1 -1
  25. data/lib/ruote/exp/fe_equals.rb +1 -1
  26. data/lib/ruote/exp/fe_error.rb +1 -1
  27. data/lib/ruote/exp/fe_filter.rb +1 -1
  28. data/lib/ruote/exp/fe_forget.rb +1 -1
  29. data/lib/ruote/exp/fe_given.rb +1 -1
  30. data/lib/ruote/exp/fe_if.rb +87 -7
  31. data/lib/ruote/exp/fe_inc.rb +1 -1
  32. data/lib/ruote/exp/fe_iterator.rb +1 -1
  33. data/lib/ruote/exp/fe_listen.rb +1 -1
  34. data/lib/ruote/exp/fe_lose.rb +1 -1
  35. data/lib/ruote/exp/fe_noop.rb +1 -1
  36. data/lib/ruote/exp/fe_on_error.rb +1 -1
  37. data/lib/ruote/exp/fe_once.rb +1 -1
  38. data/lib/ruote/exp/fe_participant.rb +49 -16
  39. data/lib/ruote/exp/fe_read.rb +1 -1
  40. data/lib/ruote/exp/fe_redo.rb +1 -1
  41. data/lib/ruote/exp/fe_ref.rb +1 -1
  42. data/lib/ruote/exp/fe_registerp.rb +1 -1
  43. data/lib/ruote/exp/fe_reserve.rb +1 -1
  44. data/lib/ruote/exp/fe_restore.rb +1 -7
  45. data/lib/ruote/exp/fe_save.rb +1 -1
  46. data/lib/ruote/exp/fe_sequence.rb +1 -1
  47. data/lib/ruote/exp/fe_set.rb +1 -1
  48. data/lib/ruote/exp/fe_stall.rb +1 -1
  49. data/lib/ruote/exp/fe_subprocess.rb +1 -1
  50. data/lib/ruote/exp/fe_that.rb +1 -1
  51. data/lib/ruote/exp/fe_undo.rb +1 -1
  52. data/lib/ruote/exp/fe_unregisterp.rb +1 -1
  53. data/lib/ruote/exp/fe_wait.rb +1 -1
  54. data/lib/ruote/exp/flow_expression.rb +117 -8
  55. data/lib/ruote/exp/iterator.rb +1 -1
  56. data/lib/ruote/exp/ro_attributes.rb +1 -1
  57. data/lib/ruote/exp/ro_filters.rb +1 -1
  58. data/lib/ruote/exp/ro_on_x.rb +4 -2
  59. data/lib/ruote/exp/ro_persist.rb +1 -1
  60. data/lib/ruote/exp/ro_timers.rb +1 -1
  61. data/lib/ruote/exp/ro_variables.rb +1 -1
  62. data/lib/ruote/extract.rb +125 -0
  63. data/lib/ruote/fei.rb +10 -73
  64. data/lib/ruote/id/mnemo_wfid_generator.rb +1 -1
  65. data/lib/ruote/id/wfid_generator.rb +1 -1
  66. data/lib/ruote/log/default_history.rb +17 -3
  67. data/lib/ruote/log/fancy_printing.rb +12 -32
  68. data/lib/ruote/log/storage_history.rb +1 -1
  69. data/lib/ruote/log/wait_logger.rb +15 -7
  70. data/lib/ruote/merge.rb +123 -0
  71. data/lib/ruote/observer.rb +1 -1
  72. data/lib/ruote/part/block_participant.rb +1 -1
  73. data/lib/ruote/part/code_participant.rb +1 -1
  74. data/lib/ruote/part/engine_participant.rb +1 -1
  75. data/lib/ruote/part/local_participant.rb +9 -1
  76. data/lib/ruote/part/no_op_participant.rb +1 -1
  77. data/lib/ruote/part/null_participant.rb +1 -1
  78. data/lib/ruote/part/participant.rb +1 -1
  79. data/lib/ruote/part/rev_participant.rb +1 -1
  80. data/lib/ruote/part/smtp_participant.rb +1 -1
  81. data/lib/ruote/part/storage_participant.rb +18 -1
  82. data/lib/ruote/part/template.rb +1 -1
  83. data/lib/ruote/reader.rb +1 -1
  84. data/lib/ruote/reader/json.rb +1 -1
  85. data/lib/ruote/reader/radial.rb +4 -4
  86. data/lib/ruote/reader/ruby_dsl.rb +1 -1
  87. data/lib/ruote/reader/xml.rb +1 -1
  88. data/lib/ruote/receiver/base.rb +13 -1
  89. data/lib/ruote/storage/base.rb +8 -14
  90. data/lib/ruote/storage/composite_storage.rb +1 -1
  91. data/lib/ruote/storage/fs_storage.rb +1 -1
  92. data/lib/ruote/storage/hash_storage.rb +2 -1
  93. data/lib/ruote/svc/dispatch_pool.rb +29 -18
  94. data/lib/ruote/svc/dollar_sub.rb +5 -8
  95. data/lib/ruote/svc/error_handler.rb +1 -1
  96. data/lib/ruote/svc/expression_map.rb +1 -1
  97. data/lib/ruote/svc/participant_list.rb +8 -5
  98. data/lib/ruote/svc/tracker.rb +154 -56
  99. data/lib/ruote/svc/treechecker.rb +1 -1
  100. data/lib/ruote/tree_dot.rb +1 -1
  101. data/lib/ruote/util/deep.rb +4 -2
  102. data/lib/ruote/util/filter.rb +1 -1
  103. data/lib/ruote/util/hashdot.rb +1 -1
  104. data/lib/ruote/util/look.rb +1 -1
  105. data/lib/ruote/util/lookup.rb +1 -1
  106. data/lib/ruote/util/misc.rb +51 -1
  107. data/lib/ruote/util/mpatch.rb +1 -1
  108. data/lib/ruote/util/ometa.rb +1 -1
  109. data/lib/ruote/util/subprocess.rb +1 -1
  110. data/lib/ruote/util/time.rb +3 -3
  111. data/lib/ruote/util/tree.rb +43 -4
  112. data/lib/ruote/version.rb +2 -2
  113. data/lib/ruote/worker.rb +30 -18
  114. data/lib/ruote/workitem.rb +1 -1
  115. data/ruote.gemspec +6 -2
  116. data/test/functional/base.rb +0 -1
  117. data/test/functional/concurrent_base.rb +1 -1
  118. data/test/functional/eft_14_cursor.rb +42 -52
  119. data/test/functional/eft_16_if.rb +24 -16
  120. data/test/functional/eft_18_concurrent_iterator.rb +31 -1
  121. data/test/functional/eft_6_concurrence.rb +149 -34
  122. data/test/functional/ft_10_dollar.rb +14 -30
  123. data/test/functional/ft_12_launchitem.rb +15 -0
  124. data/test/functional/ft_1_process_status.rb +62 -13
  125. data/test/functional/ft_20_storage_participant.rb +25 -0
  126. data/test/functional/ft_38_participant_more.rb +1 -1
  127. data/test/functional/ft_42_storage_copy.rb +1 -3
  128. data/test/functional/ft_43_participant_on_reply.rb +63 -5
  129. data/test/functional/ft_66_flank.rb +41 -0
  130. data/test/functional/ft_6_on_cancel.rb +9 -18
  131. data/test/functional/ft_71_retries.rb +25 -12
  132. data/test/functional/ft_79_attach.rb +138 -0
  133. data/test/functional/ft_7_tags.rb +27 -0
  134. data/test/functional/ft_80_pause_on_apply.rb +64 -0
  135. data/test/functional/ft_81_mutation.rb +417 -0
  136. data/test/functional/ft_82_await_attribute.rb +84 -0
  137. data/test/functional/ft_83_trackers.rb +79 -0
  138. data/test/functional/storage.rb +3 -4
  139. data/test/unit/ut_12_wait_logger.rb +41 -3
  140. data/test/unit/ut_15_util.rb +30 -0
  141. data/test/unit/ut_17_merge.rb +54 -53
  142. data/test/unit/ut_1_fei.rb +2 -2
  143. data/test/unit/ut_24_radial_reader.rb +7 -0
  144. data/test/unit/ut_26_deep.rb +14 -0
  145. data/test/unit/ut_5_tree.rb +38 -28
  146. metadata +206 -169
  147. data/couch_url.txt +0 -1
  148. data/lib/ruote/exp/merge.rb +0 -134
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2013, 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
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2013, 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
@@ -140,9 +140,9 @@ module Ruote
140
140
 
141
141
  return nil if @expressions.empty?
142
142
 
143
- @expressions.each_with_object({}) do |exp, h|
143
+ @expressions.each_with_object({}) { |exp, h|
144
144
  h[exp.fei] = exp.variables if exp.variables
145
- end
145
+ }
146
146
  end
147
147
 
148
148
  # Returns a hash tagname => fei of tags set at the root of the process
@@ -152,11 +152,7 @@ module Ruote
152
152
  #
153
153
  def tags
154
154
 
155
- if variables
156
- Hash[variables.select { |k, v| FlowExpressionId.is_a_fei?(v) }]
157
- else
158
- nil
159
- end
155
+ variables ? Hash[variables.select { |k, v| Ruote.is_a_fei?(v) }] : nil
160
156
  end
161
157
 
162
158
  # Returns a hash tagname => array of feis of all the tags set in the process
@@ -165,7 +161,7 @@ module Ruote
165
161
  def all_tags
166
162
 
167
163
  all_variables.remap do |(fei, vars), h|
168
- vars.each { |k, v| (h[k] ||= []) << v if FlowExpressionId.is_a_fei?(v) }
164
+ vars.each { |k, v| (h[k] ||= []) << v if Ruote.is_a_fei?(v) }
169
165
  end
170
166
  end
171
167
 
@@ -380,6 +376,7 @@ module Ruote
380
376
  vars = variables rescue nil
381
377
  avars = (all_variables || {}).remap { |(k, v), h| h[Ruote.sid(k)] = v }
382
378
 
379
+
383
380
  s = [ "== #{self.class} ==" ]
384
381
  s << ''
385
382
  s << " wfid: #{wfid}"
@@ -388,9 +385,15 @@ module Ruote
388
385
  s << " last_active: #{last_active}"
389
386
  s << " launched_time: #{launched_time}"
390
387
  s << ''
388
+
391
389
  s << " expressions: #{@expressions.size}"
392
390
  s << ''
393
391
  @expressions.each do |e|
392
+
393
+ eflags = %w[
394
+ flanking forgotten attached
395
+ ].each_with_object([]) { |f, a| a << f if e.h[f] }
396
+
394
397
  s << " #{e.fei.to_storage_id}"
395
398
  s << " | #{e.name}"
396
399
  s << " | _rev: #{e.h._rev.inspect}"
@@ -400,9 +403,11 @@ module Ruote
400
403
  s << " | . child-> #{Ruote.sid(ce)}"
401
404
  end if e.children.any?
402
405
  s << " | timers: #{e.h.timers.collect { |t| t[1] }}" if e.h.timers
403
- s << " | (flanking)" if e.h.flanking
406
+ s << " | tagname: #{e.h.tagname}" if e.h.tagname
407
+ s << " | (#{eflags.join(', ')})" if eflags.any?
404
408
  s << " `-parent--> #{e.h.parent_id ? e.parent_id.to_storage_id : 'nil'}"
405
409
  end
410
+
406
411
  s << ''
407
412
  s << " schedules: #{@schedules.size}"
408
413
  if @schedules.size > 0
@@ -414,6 +419,7 @@ module Ruote
414
419
  end
415
420
  s << ''
416
421
  end
422
+
417
423
  s << " stored workitems: #{@stored_workitems.size}"
418
424
 
419
425
  s << ''
@@ -494,32 +500,45 @@ module Ruote
494
500
  # Returns nil if there are no expressions (happens in the case of an
495
501
  # orphan workitem)
496
502
  #
497
- def current_tree
498
-
499
- return nil if @expressions.empty?
500
-
501
- h = Ruote.decompose_tree(original_tree)
502
-
503
- @expressions.sort { |e0, e1|
504
-
505
- e0.fei.expid <=> e1.fei.expid
506
-
507
- }.each { |e|
508
-
509
- trigger = e.tree[1]['_triggered']
510
-
511
- tree = if trigger && trigger != 'on_re_apply'
512
- t = original_tree_from_parent(e).dup
513
- t[1]['_triggered'] = trigger
514
- t
515
- else
516
- e.tree
517
- end
518
-
519
- h.merge!(Ruote.decompose_tree(tree, e.fei.expid))
520
- }
503
+ def current_tree(fexp=root_expression)
504
+
505
+ return nil unless fexp
506
+
507
+ t = Ruote.fulldup(fexp.tree)
508
+
509
+ fexp.children.each do |cfei|
510
+
511
+ cexp = fexp(cfei)
512
+ next unless cexp
513
+
514
+ ct = current_tree(cexp)
515
+
516
+ #trigger = ct[1]['_triggered']
517
+ #if trigger && trigger != 'on_re_apply'
518
+ # #
519
+ # # ignore any on_cancel / on_error / ...
520
+ # #
521
+ # #ct = t[2][cexp.child_id]
522
+ # # loses any change in the re_applied tree
523
+ # #
524
+ # # just flag the original tree as _triggered
525
+ # # loses any change in the re_applied tree
526
+ # #
527
+ # #ct = t[2][cexp.child_id]
528
+ # #ct[1]['_triggered'] = trigger
529
+ # #
530
+ # # extracts the new tree, discards the layers around it
531
+ # #
532
+ # ot = t[2][cexp.child_id]
533
+ # ct = ct[2][0][2][0]
534
+ # ct[1]['_triggered'] = [ trigger, ot[1][trigger] ].join('/')
535
+ #end
536
+ # return the real current tree, do not tweak with it!
537
+
538
+ t[2][cexp.child_id] = ct
539
+ end
521
540
 
522
- Ruote.recompose_tree(h)
541
+ t
523
542
  end
524
543
 
525
544
  # Used by Ruote::Dashboard#process and #processes
@@ -566,21 +585,15 @@ module Ruote
566
585
  }.compact
567
586
  end
568
587
 
569
- #--
570
- #def self.from_h(h)
571
- # self.new(
572
- # nil,
573
- # *%w[ expressions workitems errors schedules trackers ].map { |k| h[k] })
574
- #end
575
- #++
576
-
577
- protected
578
-
579
- def original_tree_from_parent(e)
588
+ # Given a fei, returns the flow expression with that fei (only looks
589
+ # in the expressions stored here, in this ProcessStatus instance, doesn't
590
+ # query the storage).
591
+ #
592
+ def fexp(fei)
580
593
 
581
- parent = @expressions.find { |exp| exp.fei == e.parent_id }
594
+ fei = Ruote.extract_fei(fei)
582
595
 
583
- parent ? parent.tree[2][e.fei.child_id] : e.tree
596
+ @expressions.find { |e| e.fei == fei }
584
597
  end
585
598
  end
586
599
  end
data/lib/ruote/engine.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2013, 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
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2013, 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
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2013, 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
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2013, 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
@@ -37,6 +37,7 @@ module Ruote::Exp
37
37
  class ConditionError < RuntimeError
38
38
 
39
39
  def initialize(code)
40
+
40
41
  super(
41
42
  "couldn't interpret >#{code}<, " +
42
43
  "if it comes from a ${xx} construct, please use ${\"xx} or ${'yy}")
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2013, 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
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2013, 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
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2012, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2005-2013, 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
@@ -212,49 +212,59 @@ module Ruote::Exp
212
212
  # Note: the :where guard is always about the event's workitem (not the
213
213
  # workitem as it reached the 'await' expression).
214
214
  #
215
+ #
216
+ # == note: the "await" attribute
217
+ #
218
+ # (since ruote 3.2.1)
219
+ #
220
+ # "listen" and "await" are both ruote expressions. There is also an
221
+ # attribute common to all the expressions: :await.
222
+ #
223
+ # concurrence do
224
+ # sequence do
225
+ # alice
226
+ # sequence :tag => 'stage2' do
227
+ # bob
228
+ # end
229
+ # end
230
+ # sequence do
231
+ # charly
232
+ # diana :await => 'left_tag:stage2'
233
+ # eliza
234
+ # end
235
+ # frank
236
+ # end
237
+ #
238
+ # The expressions with an await attribute suspends its application until
239
+ # the awaited event happens.
240
+ #
241
+ # This await attribute, defaults to "left_tag:", so
242
+ #
243
+ # diana :await => 'stage2'
244
+ # # is equivalent to
245
+ # diana :await => 'left_tag:stage2'
246
+ #
215
247
  class AwaitExpression < FlowExpression
216
248
 
217
249
  names :await
218
250
 
219
- INS = %w[ in entered reached]
220
- OUTS = %w[ out left ]
221
-
222
- SPLIT_R = /^(#{(INS + OUTS).join('|')})_(tag|participant)s?$/
223
- SINGLE_R = /^(tag)s|(participant|error)s?$/ # not 'tag' alone
224
-
225
251
  def apply
226
252
 
227
253
  #
228
254
  # gathering info
229
255
 
230
- direction, type, value = attributes.collect { |k, v|
231
- if m = SPLIT_R.match(k)
232
- [ m[1], m[2], v ]
233
- elsif m = SINGLE_R.match(k)
234
- [ 'in', m[1] || m[2], v ]
235
- else
236
- nil
237
- end
238
- }.compact.first
256
+ action, condition = self.class.extract_await_ac(attributes)
239
257
 
240
258
  raise ArgumentError.new(
241
259
  "couldn't determine which event to listen to from: " +
242
260
  attributes.inspect
243
- ) unless direction
261
+ ) unless action
244
262
 
245
263
  global = (attribute(:global).to_s == 'true')
246
- global = false if type == 'error'
264
+ global = false if action == 'error_intercepted'
247
265
 
248
266
  h.amerge = attribute(:merge).to_s
249
267
 
250
- action = if type == 'tag'
251
- INS.include?(direction) ? 'entered_tag' : 'left_tag'
252
- elsif type == 'participant'
253
- INS.include?(direction) ? 'dispatch' : 'receive'
254
- else # error
255
- 'error_intercepted'
256
- end
257
-
258
268
  persist_or_raise
259
269
 
260
270
  #
@@ -264,7 +274,7 @@ module Ruote::Exp
264
274
  global ? nil : h.fei['wfid'],
265
275
  action,
266
276
  Ruote.to_storage_id(h.fei),
267
- determine_condition(type, value),
277
+ condition,
268
278
  { 'action' => 'reply',
269
279
  'fei' => h.fei,
270
280
  'workitem' => 'replace',
@@ -284,12 +294,13 @@ module Ruote::Exp
284
294
 
285
295
  wi = h.applied_workitem.dup
286
296
 
287
- wi['fields'] = case h.amerge
288
- when 'ignore', 'drop' then wi['fields']
289
- when 'incoming' then wi['fields'].merge(workitem['fields'])
290
- when 'awaiting' then workitem['fields'].merge(wi['fields'])
291
- else workitem['fields'] # 'override'
292
- end
297
+ wi['fields'] =
298
+ case h.amerge
299
+ when 'ignore', 'drop' then wi['fields']
300
+ when 'incoming' then wi['fields'].merge(workitem['fields'])
301
+ when 'awaiting' then workitem['fields'].merge(wi['fields'])
302
+ else workitem['fields'] # 'override'
303
+ end
293
304
 
294
305
  #
295
306
  # actual trigger
@@ -323,34 +334,72 @@ module Ruote::Exp
323
334
  super(workitem)
324
335
  end
325
336
 
326
- # Matches Ruby class names, like "Ruote::ForcedError" or "::ArgumentError"
327
- #
328
- KLASS_R = /^(::)?([A-Z][a-z]+)+(::([A-Z][a-z]+)+)*$/
337
+ INS = %w[ in entered reached ]
338
+ OUTS = %w[ out left ]
339
+
340
+ SPLIT_R =
341
+ /^(?:(#{(INS + OUTS).join('|')})_)?(tag|participant|error)s?$/
342
+
343
+ # attribute wait regex
344
+ AAWAIT_R =
345
+ /^(?:(#{(INS + OUTS).join('|')})_)?(tag|participant)s?\s*:\s*(.+)$/
346
+
347
+ # matches Ruby class names, like "Ruote::ForcedError" or "::ArgumentError"
348
+ KLASS_R =
349
+ /^(::)?([A-Z][a-z]+)+(::([A-Z][a-z]+)+)*$/
329
350
 
330
- # Builds the condition used by the tracker service to filter msgs.
351
+ # Made into a class method, so that the :await common attribute can
352
+ # use it when parsing :await...
331
353
  #
332
- def determine_condition(type, value)
354
+ def self.extract_await_ac(atts)
355
+
356
+ direction, type, value =
357
+ atts.collect { |k, v|
358
+ if k == :await && m = AAWAIT_R.match(v)
359
+ [ m[1] || 'in', m[2], m[3] ]
360
+ elsif k == :await && v.index(':').nil?
361
+ [ 'left', 'tag', v ]
362
+ elsif m = SPLIT_R.match(k)
363
+ [ m[1] || 'in', m[2], v ]
364
+ else
365
+ nil
366
+ end
367
+ }.compact.first
368
+
369
+ return nil if direction == nil
370
+
371
+ action =
372
+ if type == 'tag'
373
+ INS.include?(direction) ? 'entered_tag' : 'left_tag'
374
+ elsif type == 'participant'
375
+ INS.include?(direction) ? 'dispatch' : 'receive'
376
+ else # error
377
+ 'error_intercepted'
378
+ end
333
379
 
334
380
  value = Ruote.comma_split(value)
335
381
 
336
- if type == 'participant'
382
+ condition =
383
+ if type == 'participant'
337
384
 
338
- { 'participant_name' => value }
385
+ { 'participant_name' => value }
339
386
 
340
- elsif type == 'error'
387
+ elsif type == 'error'
341
388
 
342
- # array or comma string or string ?
389
+ # array or comma string or string ?
343
390
 
344
- h = { 'class' => [], 'message' => [] }
391
+ h = { 'class' => [], 'message' => [] }
345
392
 
346
- value.each { |e| (KLASS_R.match(e) ? h['class'] : h['message']) << e }
393
+ value.each { |e| (KLASS_R.match(e) ? h['class'] : h['message']) << e }
347
394
 
348
- h.delete_if { |k, v| v == nil or v == [] }
395
+ h.delete_if { |k, v| v == nil or v == [] }
349
396
 
350
- else # 'tag'
397
+ else # 'tag'
351
398
 
352
- { (value.first.to_s.match(/\//) ? 'full_tag' : 'tag') => value }
353
- end
399
+ { (value.first.to_s.match(/\//) ? 'full_tag' : 'tag') => value }
400
+ end
401
+
402
+ [ action, condition ]
354
403
  end
355
404
  end
356
405
  end