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
@@ -27,7 +27,7 @@ module Ruote
27
27
 
28
28
  module HashDot
29
29
 
30
- def method_missing (m, *args)
30
+ def method_missing(m, *args)
31
31
 
32
32
  m = m.to_s
33
33
 
@@ -62,9 +62,9 @@ module Ruote
62
62
 
63
63
  module WithH
64
64
 
65
- def self.included (target)
65
+ def self.included(target)
66
66
 
67
- def target.h_reader (*names)
67
+ def target.h_reader(*names)
68
68
  names.each do |name|
69
69
  define_method(name) do
70
70
  @h[name.to_s]
@@ -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
@@ -79,11 +79,7 @@ module Ruote
79
79
  next if uninteresting.include?(o.class)
80
80
 
81
81
  stats = h[o.class.to_s] ||= [ 0, 0, 0 ]
82
- size = begin
83
- Marshal.dump(o).size
84
- rescue Exception => e
85
- 1
86
- end
82
+ size = (Marshal.dump(o).size rescue 1)
87
83
 
88
84
  stats[0] += 1
89
85
  stats[1] = size if size > stats[1]
@@ -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
@@ -29,7 +29,9 @@ module Ruote
29
29
  #
30
30
  # p Ruote.lookup(h, 'a.b.1') # => 3
31
31
  #
32
- def Ruote.lookup (collection, key, container_lookup=false)
32
+ def Ruote.lookup(collection, key, container_lookup=false)
33
+
34
+ return collection if key == '.'
33
35
 
34
36
  key, rest = pop_key(key)
35
37
  value = flookup(collection, key)
@@ -48,7 +50,7 @@ module Ruote
48
50
  #
49
51
  # h #=> { 'customer' => { 'name' => 'bravo' } }
50
52
  #
51
- def Ruote.set (collection, key, value)
53
+ def Ruote.set(collection, key, value)
52
54
 
53
55
  k, c = lookup(collection, key, true)
54
56
 
@@ -66,7 +68,7 @@ module Ruote
66
68
  # h # => { 'customer' => { 'name' => 'alpha' } }
67
69
  # r # => '1st'
68
70
  #
69
- def Ruote.unset (collection, key)
71
+ def Ruote.unset(collection, key)
70
72
 
71
73
  k, c = lookup(collection, key, true)
72
74
 
@@ -81,14 +83,14 @@ module Ruote
81
83
 
82
84
  protected # well...
83
85
 
84
- def Ruote.pop_key (key)
86
+ def Ruote.pop_key(key)
85
87
 
86
88
  ks = key.is_a?(String) ? key.split('.') : key
87
89
 
88
90
  [ narrow_key(ks.first), ks[1..-1] ]
89
91
  end
90
92
 
91
- def Ruote.narrow_key (key)
93
+ def Ruote.narrow_key(key)
92
94
 
93
95
  return 0 if key == '0'
94
96
 
@@ -98,7 +100,7 @@ module Ruote
98
100
  key
99
101
  end
100
102
 
101
- def Ruote.flookup (collection, key)
103
+ def Ruote.flookup(collection, key)
102
104
 
103
105
  value = (collection[key] rescue nil)
104
106
 
@@ -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
@@ -35,7 +35,7 @@ module Ruote
35
35
 
36
36
  # Prints the current call stack to stdout
37
37
  #
38
- def self.p_caller (*msg)
38
+ def self.p_caller(*msg)
39
39
 
40
40
  puts
41
41
  puts " == #{msg.inspect} =="
@@ -45,7 +45,7 @@ module Ruote
45
45
 
46
46
  # Deep object duplication
47
47
  #
48
- def self.fulldup (object)
48
+ def self.fulldup(object)
49
49
 
50
50
  return object.fulldup if object.respond_to?(:fulldup)
51
51
  # trusting client objects providing a fulldup() implementation
@@ -82,7 +82,7 @@ module Ruote
82
82
  value = fulldup(value)
83
83
  begin
84
84
  o.instance_variable_set(v, value)
85
- rescue Exception => e
85
+ rescue => e
86
86
  # ignore, must be readonly
87
87
  end
88
88
  end
@@ -94,21 +94,21 @@ module Ruote
94
94
  #
95
95
  # TODO : wouldn't it be better to simply use URI.parse() ?
96
96
  #
97
- def self.is_uri? (s)
97
+ def self.is_uri?(s)
98
98
 
99
99
  s && (s.index('/') || s.match(/\.[^ ]+$/))
100
100
  end
101
101
 
102
102
  # Returns a neutralized version of s, suitable as a filename.
103
103
  #
104
- def self.neutralize (s)
104
+ def self.neutralize(s)
105
105
 
106
106
  s.to_s.strip.gsub(/[ \/:;\*\\\+\?]/, '_')
107
107
  end
108
108
 
109
109
  # Tries to return an Integer or a Float from the given input. Returns
110
110
  #
111
- def self.narrow_to_number (o)
111
+ def self.narrow_to_number(o)
112
112
 
113
113
  return o if [ Fixnum, Bignum, Float ].include?(o.class)
114
114
 
@@ -119,9 +119,41 @@ module Ruote
119
119
 
120
120
  # (simpler than the one from active_support)
121
121
  #
122
- def self.constantize (s)
122
+ def self.constantize(s)
123
123
 
124
124
  s.split('::').inject(Object) { |c, n| n == '' ? c : c.const_get(n) }
125
125
  end
126
+
127
+ # # Upon receiving something like
128
+ # #
129
+ # # "(?-mix:nada)"
130
+ # #
131
+ # # will return
132
+ # #
133
+ # # /nada/
134
+ # #
135
+ # def self.regex_from_s(s)
136
+ #
137
+ # if s.is_a?(String) && m = s.match(/^\(\?-mix:(.+)\)$/)
138
+ # Regexp.new(m[1])
139
+ # else
140
+ # nil
141
+ # end
142
+ # end
143
+
144
+ REGEX_IN_STRING = /^\s*\/(.*)\/\s*$/
145
+
146
+ # regex_or_s("/nada/") #==> /nada/
147
+ # regex_or_s("nada") #==> "nada"
148
+ # regex_or_s(/nada/) #==> /nada/
149
+ #
150
+ def self.regex_or_s(s)
151
+
152
+ if s.is_a?(String) && m = REGEX_IN_STRING.match(s)
153
+ Regexp.new(m[1])
154
+ else
155
+ s
156
+ end
157
+ end
126
158
  end
127
159
 
@@ -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
@@ -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
@@ -82,19 +82,19 @@ module Ruote
82
82
  :marshal => MARSHAL, :marshal64 => MARSHAL64, :yaml => YAML
83
83
  }
84
84
 
85
- def initialize (flavour)
85
+ def initialize(flavour)
86
86
 
87
87
  @flavour = FLAVOURS[flavour] || MARSHAL64
88
88
 
89
89
  @flavour[0].call # initializes the flavour
90
90
  end
91
91
 
92
- def encode (o)
92
+ def encode(o)
93
93
 
94
94
  @flavour[1].call(o)
95
95
  end
96
96
 
97
- def decode (s)
97
+ def decode(s)
98
98
 
99
99
  @flavour[2].call(s)
100
100
  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
@@ -32,7 +32,7 @@ module Ruote
32
32
  # This method is used by the 'subprocess' expression and by the
33
33
  # EngineParticipant.
34
34
  #
35
- def self.lookup_subprocess (fexp, ref)
35
+ def self.lookup_subprocess(fexp, ref)
36
36
 
37
37
  val = fexp.lookup_variable(ref)
38
38
 
@@ -43,10 +43,11 @@ module Ruote
43
43
 
44
44
  # maybe subprocess :ref => 'uri'
45
45
 
46
- subtree = fexp.context.parser.parse(ref) rescue nil
46
+ subtree = fexp.context.reader.read(ref) rescue nil
47
47
 
48
- _, subtree = Ruote::Exp::DefineExpression.reorganize(subtree) \
49
- if subtree && Ruote::Exp::DefineExpression.is_definition?(subtree)
48
+ if subtree && is_definition_tree?(subtree)
49
+ _, subtree = Ruote::Exp::DefineExpression.reorganize(subtree)
50
+ end
50
51
 
51
52
  return [ '0', subtree ] if is_tree?(subtree)
52
53
 
@@ -55,14 +56,33 @@ module Ruote
55
56
  raise "no subprocess named '#{ref}' found"
56
57
  end
57
58
 
58
- def self.is_tree? (a)
59
+ # Returns true if the argument is a process definition tree (whose root
60
+ # is 'define', 'process_definition' or 'workflow_definition'.
61
+ #
62
+ def self.is_definition_tree?(arg)
63
+
64
+ Ruote::Exp::DefineExpression.is_definition?(arg) && is_tree?(arg)
65
+ end
59
66
 
60
- a.is_a?(Array) && a[1].is_a?(Hash) && a.size == 3
67
+ # Returns true if the given argument is a process definition tree
68
+ # (its root doesn't need to be 'define' or 'process_definition' though).
69
+ #
70
+ def self.is_tree?(arg)
71
+
72
+ arg.is_a?(Array) && arg.size == 3 &&
73
+ arg[0].is_a?(String) && arg[1].is_a?(Hash) && arg[2].is_a?(Array) &&
74
+ (arg.last.empty? || arg.last.find { |e| ! is_tree?(e) }.nil?)
61
75
  end
62
76
 
63
- def self.is_pos_tree? (a)
77
+ # Mainly used by Ruote.lookup_subprocess, returns true if the argument is
78
+ # is an array [ position, tree ].
79
+ #
80
+ def self.is_pos_tree?(arg)
64
81
 
65
- a.is_a?(Array) && a.size == 2 && a[0].is_a?(String) && is_tree?(a[1])
82
+ arg.is_a?(Array) &&
83
+ arg.size == 2 &&
84
+ arg[0].is_a?(String) &&
85
+ is_tree?(arg[1])
66
86
  end
67
87
  end
68
88
 
@@ -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
@@ -45,7 +45,7 @@ module Ruote
45
45
  #
46
46
  # like "2009/11/23 11:11:50.947109 UTC"
47
47
  #
48
- def self.time_to_utc_s (t)
48
+ def self.time_to_utc_s(t)
49
49
 
50
50
  "#{t.utc.strftime('%Y-%m-%d %H:%M:%S')}.#{sprintf('%06d', t.usec)} UTC"
51
51
  end
@@ -63,7 +63,7 @@ module Ruote
63
63
  #
64
64
  # (my prose is weak)
65
65
  #
66
- def self.s_to_at (s)
66
+ def self.s_to_at(s)
67
67
 
68
68
  at = if s.index(' ')
69
69
  #
@@ -87,7 +87,7 @@ module Ruote
87
87
 
88
88
  # Waiting for a better implementation of it in rufus-scheduler 2.0.4
89
89
  #
90
- def self.is_cron_string (s)
90
+ def self.is_cron_string(s)
91
91
 
92
92
  ss = s.split(' ')
93
93
 
@@ -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
@@ -28,7 +28,7 @@ module Ruote
28
28
  # Turning a tree into a numbered string view
29
29
  #
30
30
  # require 'ruote/util/tree'
31
- # require 'ruote/parser/ruby_dsl'
31
+ # require 'ruote/reader/ruby_dsl'
32
32
  #
33
33
  # pdef = Ruote.process_definition :name => 'def0' do
34
34
  # sequence do
@@ -47,7 +47,7 @@ module Ruote
47
47
  # # 0_0_0 alpha {}
48
48
  # # 0_0_1 bravo {}
49
49
  #
50
- def Ruote.tree_to_s (tree, expid='0')
50
+ def Ruote.tree_to_s(tree, expid='0')
51
51
 
52
52
  d = expid.split('_').size - 1
53
53
  s = "#{' ' * d * 2}#{expid} #{tree[0]} #{tree[1].inspect}\n"
data/lib/ruote/version.rb CHANGED
@@ -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,6 @@
23
23
  #++
24
24
 
25
25
  module Ruote
26
- VERSION = '2.1.11'
26
+ VERSION = '2.2.0'
27
27
  end
28
28
 
data/lib/ruote/worker.rb CHANGED
@@ -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
@@ -47,7 +47,9 @@ module Ruote
47
47
  attr_reader :run_thread
48
48
  attr_reader :running
49
49
 
50
- def initialize (storage)
50
+ # Given a storage, creates a new instance of a Worker.
51
+ #
52
+ def initialize(storage)
51
53
 
52
54
  @subscribers = []
53
55
  # must be ready before the storage is created
@@ -93,17 +95,21 @@ module Ruote
93
95
  @run_thread.join if @run_thread
94
96
  end
95
97
 
96
- def subscribe (actions, subscriber)
98
+ # Loggers and trackers call this method when subscribing for events /
99
+ # actions in this worker.
100
+ #
101
+ def subscribe(actions, subscriber)
97
102
 
98
103
  @subscribers << [ actions, subscriber ]
99
104
  end
100
105
 
106
+ # Shuts down this worker (makes sure it won't fetch further messages
107
+ # and schedules).
108
+ #
101
109
  def shutdown
102
110
 
103
111
  @running = false
104
112
 
105
- return unless @run_thread
106
-
107
113
  begin
108
114
  @run_thread.join
109
115
  rescue Exception => e
@@ -138,6 +144,9 @@ module Ruote
138
144
 
139
145
  protected
140
146
 
147
+ # One worker step, fetches schedules and triggers those whose time has
148
+ # came, then fetches msgs and processes them.
149
+ #
141
150
  def step
142
151
 
143
152
  now = Time.now.utc
@@ -149,9 +158,7 @@ module Ruote
149
158
 
150
159
  @last_time = now
151
160
 
152
- @storage.get_schedules(delta, now).each do |sche|
153
- trigger(sche)
154
- end
161
+ @storage.get_schedules(delta, now).each { |sche| trigger(sche) }
155
162
  end
156
163
 
157
164
  # msgs
@@ -193,7 +200,14 @@ module Ruote
193
200
  end
194
201
  end
195
202
 
196
- def trigger (schedule)
203
+ # Given a schedule, attempts to trigger it.
204
+ #
205
+ # It first tries to
206
+ # reserve the schedule. If the reservation fails (another worker
207
+ # was successful probably), false is returned. The schedule is
208
+ # triggered if the reservation was successful, true is returned.
209
+ #
210
+ def trigger(schedule)
197
211
 
198
212
  msg = Ruote.fulldup(schedule['msg'])
199
213
 
@@ -204,9 +218,17 @@ module Ruote
204
218
  true
205
219
  end
206
220
 
207
- def process (msg)
208
-
209
- return false if cannot_handle(msg)
221
+ # Processes one msg.
222
+ #
223
+ # Will return false immediately if the msg reservation failed (another
224
+ # worker grabbed the message.
225
+ #
226
+ # Else will execute the action ordered in the msg, and return true.
227
+ #
228
+ # Exceptions in execution are intercepted here and passed to the
229
+ # engine's (context's) error_handler.
230
+ #
231
+ def process(msg)
210
232
 
211
233
  return false unless @storage.reserve(msg)
212
234
 
@@ -238,7 +260,7 @@ module Ruote
238
260
 
239
261
  notify(msg)
240
262
 
241
- rescue Exception => exception
263
+ rescue => exception
242
264
 
243
265
  @context.error_handler.msg_handle(msg, exception)
244
266
  end
@@ -246,7 +268,10 @@ module Ruote
246
268
  true
247
269
  end
248
270
 
249
- def notify (msg)
271
+ # Given a successfully executed msg, now notifies all the subscribers
272
+ # interested in the kind of action the msg ordered.
273
+ #
274
+ def notify(msg)
250
275
 
251
276
  @subscribers.each do |actions, subscriber|
252
277
 
@@ -256,20 +281,12 @@ module Ruote
256
281
  end
257
282
  end
258
283
 
259
- # Should always return false. Except when the message is a 'dispatch'
260
- # and it's for a participant only available to an 'engine_worker'
261
- # (block participants, stateful participants)
262
- #
263
- def cannot_handle (msg)
264
-
265
- return false if msg['action'] != 'dispatch'
266
-
267
- @context.engine.nil? && msg['for_engine_worker?']
268
- end
269
-
270
284
  # Works for both the 'launch' and the 'apply' msgs.
271
285
  #
272
- def launch (msg)
286
+ # Creates a new expression, gives and applies it with the
287
+ # workitem contained in the msg.
288
+ #
289
+ def launch(msg)
273
290
 
274
291
  tree = msg['tree']
275
292
  variables = msg['variables']
@@ -283,7 +300,7 @@ module Ruote
283
300
  'fei' => msg['fei'] || {
284
301
  'engine_id' => @context.engine_id,
285
302
  'wfid' => msg['wfid'],
286
- 'sub_wfid' => msg['sub_wfid'],
303
+ 'subid' => Ruote.generate_subid(msg.inspect),
287
304
  'expid' => '0' },
288
305
  'parent_id' => msg['parent_id'],
289
306
  'original_tree' => tree,
@@ -296,7 +313,6 @@ module Ruote
296
313
 
297
314
  exp_class = Ruote::Exp::RefExpression
298
315
 
299
- #elsif msg['action'] == 'launch' && exp_class == Ruote::Exp::DefineExpression
300
316
  elsif is_launch?(msg, exp_class)
301
317
 
302
318
  def_name, tree = Ruote::Exp::DefineExpression.reorganize(tree)
@@ -307,17 +323,24 @@ module Ruote
307
323
  exp = exp_class.new(@context, exp_hash.merge!('original_tree' => tree))
308
324
 
309
325
  exp.initial_persist
310
- exp.do_apply
326
+ exp.do_apply(msg)
311
327
  end
312
328
 
313
- def is_launch? (msg, exp_class)
329
+ # Returns true if the msg is a "launch" (ie not a simply "apply").
330
+ #
331
+ def is_launch?(msg, exp_class)
314
332
 
315
333
  return false if exp_class != Ruote::Exp::DefineExpression
316
334
  return true if msg['action'] == 'launch'
317
335
  (msg['trigger'] == 'on_re_apply')
318
336
  end
319
337
 
320
- def cancel_process (msg)
338
+ # Handles a 'cancel_process' msg (translates it into a "cancel root
339
+ # expression of that process" msg).
340
+ #
341
+ # Also works for 'kill_process' msgs.
342
+ #
343
+ def cancel_process(msg)
321
344
 
322
345
  root = @storage.find_root_expression(msg['wfid'])
323
346
 
@@ -332,7 +355,7 @@ module Ruote
332
355
  'flavour' => flavour)
333
356
  end
334
357
 
335
- alias :kill_process :cancel_process
358
+ alias kill_process cancel_process
336
359
  end
337
360
  end
338
361