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
data/lib/ruote/fei.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
@@ -22,6 +22,8 @@
22
22
  # Made in Japan.
23
23
  #++
24
24
 
25
+ require 'digest/md5'
26
+
25
27
  require 'ruote/version'
26
28
  require 'ruote/workitem'
27
29
  require 'ruote/util/misc'
@@ -34,7 +36,7 @@ module Ruote
34
36
  #
35
37
  # Ruote::FlowExpressionId.to_storage_id(fei)
36
38
  #
37
- def self.to_storage_id (fei)
39
+ def self.to_storage_id(fei)
38
40
 
39
41
  Ruote::FlowExpressionId.to_storage_id(fei)
40
42
  end
@@ -43,11 +45,40 @@ module Ruote
43
45
  #
44
46
  # Ruote::FlowExpressionId.to_storage_id(fei)
45
47
  #
46
- def self.sid (fei)
48
+ def self.sid(fei)
47
49
 
48
50
  Ruote::FlowExpressionId.to_storage_id(fei)
49
51
  end
50
52
 
53
+ # A shortcut for
54
+ #
55
+ # Ruote::FlowExpressionId.is_a_fei?(o)
56
+ #
57
+ def self.is_a_fei?(o)
58
+
59
+ Ruote::FlowExpressionId.is_a_fei?(o)
60
+ end
61
+
62
+ # Will do its best to return a wfid (String) or a fei (Hash instance)
63
+ # extract from the given o argument.
64
+ #
65
+ def self.extract_id(o)
66
+
67
+ return o if o.is_a?(String) and o.index('!').nil? # wfid
68
+
69
+ Ruote::FlowExpressionId.extract_h(o)
70
+ end
71
+
72
+ # This function is used to generate the subids. Each flow
73
+ # expression receives such an id (it's useful for cursors, loops and
74
+ # forgotten branches).
75
+ #
76
+ def self.generate_subid(salt)
77
+
78
+ Digest::MD5.hexdigest(
79
+ "#{rand}-#{salt}-#{$$}-#{Thread.current.object_id}#{Time.now.to_f}")
80
+ end
81
+
51
82
  #
52
83
  # The FlowExpressionId (fei for short) is an process expression identifier.
53
84
  # Each expression when instantiated gets a unique fei.
@@ -60,7 +91,7 @@ module Ruote
60
91
  # Feis contain four pieces of information :
61
92
  #
62
93
  # * wfid : workflow instance id, the identifier for the process instance
63
- # * sub_wfid : the identifier for the sub process within the main instance
94
+ # * subid : a unique identifier for expressions (useful in loops)
64
95
  # * expid : the expression id, where in the process tree
65
96
  # * engine_id : only relevant in multi engine scenarii (defaults to 'engine')
66
97
  #
@@ -70,44 +101,39 @@ module Ruote
70
101
 
71
102
  attr_reader :h
72
103
 
73
- def initialize (h)
104
+ def initialize(h)
74
105
 
75
106
  @h = h
76
107
  class << h; include Ruote::HashDot; end
77
- end
78
-
79
- def expid
80
- @h['expid']
81
- end
82
108
 
83
- def wfid
84
- @h['wfid']
109
+ @h['subid'] = @h.delete('sub_wfid') if @h['sub_wfid']
110
+ # TODO : for 2.1.13, remove this
85
111
  end
86
112
 
87
- def sub_wfid
88
- @h['sub_wfid']
89
- end
113
+ def expid; @h['expid']; end
114
+ def wfid; @h['wfid']; end
115
+ def engine_id; @h['engine_id']; end
116
+ def subid; @h['subid']; end
90
117
 
91
- def engine_id
92
- @h['engine_id']
93
- end
118
+ alias sub_wfid subid
94
119
 
95
120
  def to_storage_id
96
- "#{@h['expid']}!#{@h['sub_wfid']}!#{@h['wfid']}"
121
+ "#{@h['expid']}!#{@h['subid']}!#{@h['wfid']}"
97
122
  end
98
-
99
123
  alias sid to_storage_id
100
124
 
101
- def self.to_storage_id (hfei)
125
+ def self.to_storage_id(hfei)
102
126
 
103
127
  hfei.respond_to?(:to_storage_id) ?
104
128
  hfei.to_storage_id :
105
- "#{hfei['expid']}!#{hfei['sub_wfid']}!#{hfei['wfid']}"
129
+ "#{hfei['expid']}!#{hfei['subid'] || hfei['sub_wfid']}!#{hfei['wfid']}"
130
+
131
+ # TODO : for 2.1.13, remove the subid || sub_wfid trick
106
132
  end
107
133
 
108
134
  # Turns the result of to_storage_id back to a FlowExpressionId instance.
109
135
  #
110
- def self.from_id (s, engine_id='engine')
136
+ def self.from_id(s, engine_id='engine')
111
137
 
112
138
  extract("#{engine_id}!#{s}")
113
139
  end
@@ -116,14 +142,19 @@ module Ruote
116
142
  # '0_5_7', the child_id will be '7'.
117
143
  #
118
144
  def child_id
145
+
119
146
  h.expid.split(CHILD_SEP).last.to_i
120
147
  end
121
148
 
122
149
  def hash
150
+
123
151
  to_storage_id.hash
124
152
  end
125
153
 
126
- def == (other)
154
+ # Returns true if the other is a FlowExpressionId instance and it
155
+ # points to the same expression as this one.
156
+ #
157
+ def ==(other)
127
158
 
128
159
  return false unless other.is_a?(Ruote::FlowExpressionId)
129
160
 
@@ -132,27 +163,34 @@ module Ruote
132
163
 
133
164
  alias eql? ==
134
165
 
166
+ SUBS = %w[ subid sub_wfid ]
167
+ IDS = %w[ engine_id expid wfid ]
168
+
135
169
  # Returns true if the h is a representation of a FlowExpressionId instance.
136
170
  #
137
- def self.is_a_fei? (h)
171
+ def self.is_a_fei?(h)
138
172
 
139
- h.respond_to?(:keys) &&
140
- (h.keys - [ 'sub_wfid' ]).sort == %w[ engine_id expid wfid ]
173
+ h.respond_to?(:keys) && (h.keys - SUBS).sort == IDS
141
174
  end
142
175
 
143
176
  # Returns child_id... For an expid of '0_1_4', this will be 4.
144
177
  #
145
- def self.child_id (h)
178
+ def self.child_id(h)
179
+
146
180
  h['expid'].split(CHILD_SEP).last.to_i
147
181
  end
148
182
 
149
183
  def to_h
184
+
150
185
  @h
151
186
  end
152
187
 
153
- def self.direct_child? (parent_fei, other_fei)
188
+ # Returns true if other_fei is the fei of a child expression of
189
+ # parent_fei.
190
+ #
191
+ def self.direct_child?(parent_fei, other_fei)
154
192
 
155
- %w[ sub_wfid wfid engine_id ].each do |k|
193
+ %w[ wfid engine_id ].each do |k|
156
194
  return false if parent_fei[k] != other_fei[k]
157
195
  end
158
196
 
@@ -166,7 +204,7 @@ module Ruote
166
204
  #
167
205
  # Uses .extract_h
168
206
  #
169
- def self.extract (arg)
207
+ def self.extract(arg)
170
208
 
171
209
  FlowExpressionId.new(extract_h(arg))
172
210
  end
@@ -174,7 +212,7 @@ module Ruote
174
212
  # Attempts at extracting a FlowExpressionId (as a Hash instance) from the
175
213
  # given argument (workitem, string, ...)
176
214
  #
177
- def self.extract_h (arg)
215
+ def self.extract_h(arg)
178
216
 
179
217
  if arg.is_a?(Hash)
180
218
  return arg if arg['expid']
@@ -191,7 +229,9 @@ module Ruote
191
229
 
192
230
  return {
193
231
  'engine_id' => ss[-4] || 'engine',
194
- 'expid' => ss[-3], 'sub_wfid' => ss[-2], 'wfid' => ss[-1] }
232
+ 'expid' => ss[-3],
233
+ 'subid' => ss[-2],
234
+ 'wfid' => ss[-1] }
195
235
  end
196
236
 
197
237
  raise ArgumentError.new(
@@ -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
@@ -27,7 +27,7 @@ module Ruote
27
27
 
28
28
  class WfidGenerator
29
29
 
30
- def initialize (context)
30
+ def initialize(context)
31
31
 
32
32
  @context = context
33
33
 
@@ -54,14 +54,21 @@ module Ruote
54
54
 
55
55
  @last['raw'] = raw.to_f
56
56
 
57
- last = @context.storage.put(@last)
57
+ last = @context.storage.put(@last, :update_rev => true)
58
58
 
59
- if last
59
+ if last == true
60
+ #
61
+ # 'last' is gone, have to put new one
62
+ @last.delete('_rev')
63
+ get_raw
64
+
65
+ elsif last
60
66
  #
61
67
  # put failed, have to re-ask
62
68
  #
63
69
  @last = last
64
70
  get_raw
71
+
65
72
  else
66
73
  #
67
74
  # put successful, we can build a new wfid
@@ -0,0 +1,122 @@
1
+ #--
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Ruote
27
+
28
+ #
29
+ # A default history implementation, only keeps the most recent stuff
30
+ # in memory.
31
+ #
32
+ # NOTE : this default history is useless when there are multiple workers.
33
+ # It only keeps track of the 'local' worker if there is one present.
34
+ #
35
+ class DefaultHistory
36
+
37
+ DATE_REGEX = /!(\d{4}-\d{2}-\d{2})!/
38
+ DEFAULT_MAX_SIZE = 1000
39
+
40
+ def initialize(context, options={})
41
+
42
+ @context = context
43
+ @options = options
44
+
45
+ @history = []
46
+
47
+ @context.worker.subscribe(:all, self) if @context.worker
48
+ # only care about logging if there is a worker present
49
+ end
50
+
51
+ # Returns all the msgs (events), most recent one is last.
52
+ #
53
+ def all
54
+
55
+ @history
56
+ end
57
+
58
+ # Returns all the wfids for which some piece of history is kept.
59
+ #
60
+ def wfids
61
+
62
+ @history.collect { |msg|
63
+ msg['wfid'] || (msg['fei']['wfid'] rescue nil)
64
+ }.compact.uniq.sort
65
+ end
66
+
67
+ # Returns all the msgs (events) for a given wfid. (Well, all the msgs
68
+ # that are kept.
69
+ #
70
+ def by_process(wfid)
71
+
72
+ @history.select { |msg|
73
+ (msg['wfid'] || (msg['fei']['wfid'] rescue nil)) == wfid
74
+ }
75
+ end
76
+ alias by_wfid by_process
77
+
78
+ # Returns an array [ most recent date, oldest date ] (Time instances).
79
+ #
80
+ def range
81
+
82
+ now = Time.now
83
+
84
+ [ (Time.parse(@history.first['seen_at']) rescue now),
85
+ (Time.parse(@history.last['seen_at']) rescue now) ]
86
+ end
87
+
88
+ def by_date(date)
89
+
90
+ d = Time.parse(date.to_s).utc.strftime('%Y-%m-%d')
91
+
92
+ @history.select { |m| Time.parse(m['seen_at']).strftime('%Y-%m-%d') == d }
93
+ end
94
+
95
+ #def history_to_tree (wfid)
96
+ # # (NOTE why not ?)
97
+ #end
98
+
99
+ # Forgets all the stored msgs.
100
+ #
101
+ def clear!
102
+
103
+ @history.clear
104
+ end
105
+
106
+ # This is the method called by the workqueue. Incoming engine events
107
+ # are 'processed' here.
108
+ #
109
+ def notify(msg)
110
+
111
+ msg = Ruote.fulldup(msg)
112
+ msg['seen_at'] = Ruote.now_to_utc_s
113
+
114
+ @history << msg
115
+
116
+ while (@history.size > (@options[:max_size] || DEFAULT_MAX_SIZE)) do
117
+ @history.shift
118
+ end
119
+ end
120
+ end
121
+ end
122
+
@@ -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
@@ -64,7 +64,7 @@ module Ruote
64
64
  # 47 White
65
65
  #++
66
66
 
67
- def color (mod, s, clear=false)
67
+ def color(mod, s, clear=false)
68
68
 
69
69
  return s if Ruote::WIN
70
70
  return s unless STDOUT.tty?
@@ -72,7 +72,7 @@ module Ruote
72
72
  "[#{mod}m#{s}#{clear ? '' : "[#{@color}m"}"
73
73
  end
74
74
 
75
- def pretty_print (msg)
75
+ def pretty_print(msg)
76
76
 
77
77
  @count += 1
78
78
  @count = 0 if @count > 9
@@ -83,8 +83,9 @@ module Ruote
83
83
  depth = fei ? fei['expid'].split('_').size : 0
84
84
 
85
85
  i = fei ?
86
- [ fei['wfid'], fei['sub_wfid'], fei['expid'] ].join(' ') :
86
+ [ fei['wfid'], (fei['subid'] || '')[0, 5], fei['expid'] ].join(' ') :
87
87
  msg['wfid']
88
+ wfid = fei ? fei['wfid'] : msg['wfid']
88
89
 
89
90
  rest = msg.dup
90
91
  %w[
@@ -102,6 +103,10 @@ module Ruote
102
103
  v['fields'].size ]
103
104
  end
104
105
 
106
+ #if t = rest.delete('tree')
107
+ # rest[:t] = color(37, t.inspect, true)
108
+ #end
109
+
105
110
  { 'tree' => :t, 'parent_id' => :pi }.each do |k0, k1|
106
111
  if v = rest.delete(k0)
107
112
  rest[k1] = v
@@ -127,10 +132,33 @@ module Ruote
127
132
  else action
128
133
  end
129
134
 
130
- color(
131
- @color,
132
- "#{@count} #{ei} #{' ' * depth}#{action} * #{i} #{rest.inspect}",
133
- true)
135
+ if msg['action'] == 'error_intercepted'
136
+
137
+ tail = []
138
+ tail << " #{wfid} #{rest['error']['class']}"
139
+ tail << " #{wfid} #{rest['error']['message']}"
140
+ rest['error']['trace'].each do |line|
141
+ tail << " #{wfid} #{line}"
142
+ end
143
+
144
+ color(
145
+ @color,
146
+ "#{@count} #{ei} #{' ' * depth}#{action} * #{i}",
147
+ true
148
+ ) +
149
+ "\n" +
150
+ color(
151
+ @color,
152
+ tail.join("\n"),
153
+ true)
154
+
155
+ else
156
+
157
+ color(
158
+ @color,
159
+ "#{@count} #{ei} #{' ' * depth}#{action} * #{i} #{rest.inspect}",
160
+ true)
161
+ end
134
162
  end
135
163
  end
136
164
  end