ruote 2.1.10 → 2.1.11

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 (94) hide show
  1. data/CHANGELOG.txt +51 -1
  2. data/CREDITS.txt +9 -0
  3. data/README.rdoc +13 -0
  4. data/Rakefile +50 -21
  5. data/TODO.txt +42 -4
  6. data/examples/pong.rb +37 -0
  7. data/lib/ruote/context.rb +19 -9
  8. data/lib/ruote/engine/process_error.rb +10 -0
  9. data/lib/ruote/engine/process_status.rb +140 -41
  10. data/lib/ruote/engine.rb +394 -27
  11. data/lib/ruote/exp/command.rb +2 -0
  12. data/lib/ruote/exp/fe_concurrence.rb +8 -0
  13. data/lib/ruote/exp/fe_concurrent_iterator.rb +3 -0
  14. data/lib/ruote/exp/fe_cursor.rb +48 -4
  15. data/lib/ruote/exp/fe_iterator.rb +40 -0
  16. data/lib/ruote/exp/fe_listen.rb +3 -3
  17. data/lib/ruote/exp/fe_participant.rb +30 -12
  18. data/lib/ruote/exp/fe_ref.rb +126 -0
  19. data/lib/ruote/exp/fe_subprocess.rb +20 -1
  20. data/lib/ruote/exp/fe_wait.rb +4 -1
  21. data/lib/ruote/exp/fe_when.rb +7 -10
  22. data/lib/ruote/exp/flowexpression.rb +23 -12
  23. data/lib/ruote/exp/ro_attributes.rb +5 -8
  24. data/lib/ruote/exp/ro_variables.rb +4 -2
  25. data/lib/ruote/fei.rb +2 -0
  26. data/lib/ruote/id/wfid_generator.rb +1 -1
  27. data/lib/ruote/log/pretty.rb +137 -0
  28. data/lib/ruote/log/storage_history.rb +1 -1
  29. data/lib/ruote/log/test_logger.rb +51 -126
  30. data/lib/ruote/log/wait_logger.rb +8 -13
  31. data/lib/ruote/parser/ruby_dsl.rb +4 -4
  32. data/lib/ruote/parser.rb +2 -2
  33. data/lib/ruote/part/block_participant.rb +1 -1
  34. data/lib/ruote/part/engine_participant.rb +1 -1
  35. data/lib/ruote/part/storage_participant.rb +27 -28
  36. data/lib/ruote/part/template.rb +8 -3
  37. data/lib/ruote/receiver/base.rb +24 -6
  38. data/lib/ruote/storage/base.rb +76 -11
  39. data/lib/ruote/storage/fs_storage.rb +10 -0
  40. data/lib/ruote/storage/hash_storage.rb +19 -8
  41. data/lib/ruote/{part → svc}/dispatch_pool.rb +3 -2
  42. data/lib/ruote/svc/dollar_sub.rb +265 -0
  43. data/lib/ruote/{error_handler.rb → svc/error_handler.rb} +6 -1
  44. data/lib/ruote/{exp → svc}/expression_map.rb +31 -37
  45. data/lib/ruote/{part → svc}/participant_list.rb +165 -25
  46. data/lib/ruote/{evt → svc}/tracker.rb +0 -0
  47. data/lib/ruote/{util → svc}/treechecker.rb +0 -0
  48. data/lib/ruote/util/look.rb +4 -1
  49. data/lib/ruote/util/ometa.rb +21 -5
  50. data/lib/ruote/{subprocess.rb → util/subprocess.rb} +0 -0
  51. data/lib/ruote/version.rb +1 -1
  52. data/lib/ruote/worker.rb +29 -69
  53. data/lib/ruote/workitem.rb +28 -1
  54. data/ruote.gemspec +26 -22
  55. data/test/functional/base.rb +3 -0
  56. data/test/functional/concurrent_base.rb +1 -0
  57. data/test/functional/crunner.sh +1 -1
  58. data/test/functional/ct_0_concurrence.rb +6 -0
  59. data/test/functional/ct_1_iterator.rb +3 -0
  60. data/test/functional/ct_2_cancel.rb +5 -0
  61. data/test/functional/eft_13_iterator.rb +39 -4
  62. data/test/functional/eft_14_cursor.rb +39 -0
  63. data/test/functional/eft_30_ref.rb +140 -0
  64. data/test/functional/eft_3_participant.rb +25 -23
  65. data/test/functional/ft_10_dollar.rb +17 -1
  66. data/test/functional/ft_14_re_apply.rb +76 -0
  67. data/test/functional/ft_1_process_status.rb +170 -29
  68. data/test/functional/ft_20_storage_participant.rb +14 -0
  69. data/test/functional/ft_24_block_participants.rb +1 -1
  70. data/test/functional/ft_26_participant_timeout.rb +93 -0
  71. data/test/functional/ft_2_errors.rb +24 -17
  72. data/test/functional/ft_30_smtp_participant.rb +7 -2
  73. data/test/functional/ft_38_participant_more.rb +15 -0
  74. data/test/functional/ft_39_wait_for.rb +34 -1
  75. data/test/functional/ft_3_participant_registration.rb +270 -2
  76. data/test/functional/ft_40_wait_logger.rb +61 -0
  77. data/test/functional/ft_42_storage_copy.rb +4 -0
  78. data/test/functional/{ft_40_participant_on_reply.rb → ft_43_participant_on_reply.rb} +17 -0
  79. data/test/functional/ft_44_var_participant.rb +35 -0
  80. data/test/functional/ft_45_participant_accept.rb +64 -0
  81. data/test/functional/ft_46_launch_single.rb +49 -0
  82. data/test/functional/ft_5_on_error.rb +39 -1
  83. data/test/functional/storage_helper.rb +7 -1
  84. data/test/test_helper.rb +1 -1
  85. data/test/unit/storage.rb +105 -32
  86. data/test/unit/ut_0_ruby_parser.rb +31 -1
  87. data/test/unit/ut_16_parser.rb +20 -0
  88. data/test/unit/ut_19_part_template.rb +11 -1
  89. data/test/unit/ut_20_composite_storage.rb +1 -1
  90. data/test/unit/ut_4_expmap.rb +1 -1
  91. data/test/unit/ut_6_condition.rb +2 -2
  92. metadata +112 -74
  93. data/lib/ruote/exp/raw.rb +0 -44
  94. data/lib/ruote/util/dollar.rb +0 -193
@@ -78,6 +78,17 @@ module Ruote::Exp
78
78
  # end
79
79
  #
80
80
  #
81
+ # == the classical case
82
+ #
83
+ # Iterating over a workitem field :
84
+ #
85
+ # pdef = Ruote.process_definition :name => 'test' do
86
+ # iterator :on_field => 'customers', :to_f => 'customer'
87
+ # participant '${f:customer}'
88
+ # end
89
+ # end
90
+ #
91
+ #
81
92
  # == break/rewind/continue/skip/jump
82
93
  #
83
94
  # The 'iterator' expression understands a certain the following commands :
@@ -97,6 +108,35 @@ module Ruote::Exp
97
108
  # end
98
109
  # end
99
110
  #
111
+ # == iterator command in the workitem
112
+ #
113
+ # It's OK to issue a command to the iterator from a participant via the
114
+ # workitem.
115
+ #
116
+ # pdef = Ruote.process_definition do
117
+ # iterator :times => 10
118
+ # sequence do
119
+ # participant 'accounting'
120
+ # participant 'adjust'
121
+ # end
122
+ # end
123
+ # end
124
+ #
125
+ # where
126
+ #
127
+ # class Adjust
128
+ # include Ruote::LocalParticipant
129
+ # def consume (workitem)
130
+ # workitem.command = 'break' if workitem.fields['amount'] > 10_000
131
+ # reply_to_engine(workitem)
132
+ # end
133
+ # def cancel (fei, flavour)
134
+ # end
135
+ # end
136
+ #
137
+ # A completely stupid example... The adjust participant will make the
138
+ # loop break if the amount reaches 10_000 (euros?).
139
+ #
100
140
  #
101
141
  # == break/rewind/continue/skip/jump with :ref
102
142
  #
@@ -136,13 +136,13 @@ module Ruote::Exp
136
136
  h.lmerge = attribute(:merge).to_s
137
137
  h.lmerge = 'true' if h.lmerge == ''
138
138
 
139
- h.wfid = attribute(:wfid).to_s
140
- h.wfid = %w[ same current true ].include?(h.wfid)
139
+ h.lwfid = attribute(:wfid).to_s
140
+ h.lwfid = %w[ same current true ].include?(h.lwfid)
141
141
 
142
142
  persist_or_raise
143
143
 
144
144
  @context.tracker.add_tracker(
145
- h.wfid ? h.fei['wfid'] : nil,
145
+ h.lwfid ? h.fei['wfid'] : nil,
146
146
  h.upon,
147
147
  h.fei,
148
148
  { 'participant_name' => h.to },
@@ -123,20 +123,26 @@ module Ruote::Exp
123
123
  #
124
124
  h_reader :dispatched
125
125
 
126
+ h_reader :participant
127
+
126
128
  def apply
127
129
 
128
130
  #
129
131
  # determine participant
130
132
 
131
- h.participant_name = attribute(:ref) || attribute_text
133
+ h.participant_name = (attribute(:ref) || attribute_text).to_s
132
134
 
133
- h.participant_name = h.participant_name.to_s
135
+ raise ArgumentError.new(
136
+ "no participant name specified"
137
+ ) if h.participant_name == ''
134
138
 
135
- if h.participant_name == ''
136
- raise ArgumentError.new("no participant name specified")
137
- end
139
+ participant_info =
140
+ h.participant ||
141
+ @context.plist.lookup_info(h.participant_name, h.applied_workitem)
138
142
 
139
- participant_info = @context.plist.lookup_info(h.participant_name)
143
+ unless participant_info.respond_to?(:consume)
144
+ h.participant = participant_info
145
+ end
140
146
 
141
147
  raise(ArgumentError.new(
142
148
  "no participant named #{h.participant_name.inspect}")
@@ -159,6 +165,7 @@ module Ruote::Exp
159
165
  'dispatch',
160
166
  'fei' => h.fei,
161
167
  'participant_name' => h.participant_name,
168
+ 'participant' => h.participant,
162
169
  'workitem' => h.applied_workitem,
163
170
  'for_engine_worker?' => (participant_info.class != Array))
164
171
  end
@@ -177,14 +184,18 @@ module Ruote::Exp
177
184
  'dispatch_cancel',
178
185
  'fei' => h.fei,
179
186
  'participant_name' => h.participant_name,
187
+ 'participant' => h.participant,
180
188
  'flavour' => flavour,
181
189
  'workitem' => h.applied_workitem)
182
190
  end
183
191
 
184
192
  def reply (workitem)
185
193
 
186
- pa = @context.plist.lookup(
187
- workitem['participant_name'], :on_reply => true)
194
+ pinfo =
195
+ h.participant ||
196
+ @context.plist.lookup_info(h.participant_name, workitem)
197
+
198
+ pa = @context.plist.instantiate(pinfo, :if_respond_to? => :on_reply)
188
199
 
189
200
  pa.on_reply(Ruote::Workitem.new(workitem)) if pa
190
201
 
@@ -227,10 +238,17 @@ module Ruote::Exp
227
238
  #
228
239
  def schedule_timeout (p_info)
229
240
 
230
- timeout =
231
- attribute(:timeout) ||
232
- (p_info.timeout rescue nil) ||
233
- (p_info.is_a?(Array) ? p_info.last['timeout'] : nil)
241
+ timeout = attribute(:timeout)
242
+
243
+ unless timeout
244
+
245
+ pa = @context.plist.instantiate(p_info, :if_respond_to? => :timeout)
246
+
247
+ timeout = pa.timeout if pa && pa.method(:timeout).arity == 0
248
+ #
249
+ # the arity check is for jruby which seems to have a timeout
250
+ # method here and there
251
+ end
234
252
 
235
253
  do_schedule_timeout(timeout)
236
254
  end
@@ -0,0 +1,126 @@
1
+ #--
2
+ # Copyright (c) 2005-2010, 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::Exp
27
+
28
+ #
29
+ # Sometimes you don't know at 'design time', if you want to trigger a
30
+ # participant or subprocess.
31
+ #
32
+ # Ruote.process_definition do
33
+ # sequence do
34
+ # participant 'alice'
35
+ # ref '${solver}'
36
+ # participant 'charlie'
37
+ # end
38
+ # end
39
+ #
40
+ # In this process, solver's name could be a participant name or a subprocess
41
+ # name.
42
+ #
43
+ # Subprocesses have the priority over participants.
44
+ #
45
+ # Note : this expression is used by the worker when substituting unknown
46
+ # expression names with participant or subprocess refs.
47
+ #
48
+ class RefExpression < FlowExpression
49
+
50
+ names :ref
51
+
52
+ def apply
53
+
54
+ key = (attribute(:ref) || attribute_text).to_s
55
+
56
+ if name != 'ref'
57
+ key = name
58
+ tree[1]['ref'] = key
59
+ end
60
+
61
+ key2, value = iterative_var_lookup(key)
62
+
63
+ tree[1]['ref'] = key2 if key2
64
+ tree[1]['original_ref'] = key if key2 != key
65
+
66
+ unless value
67
+ #
68
+ # seems like it's participant
69
+
70
+ @h['participant'] =
71
+ @context.plist.lookup_info(tree[1]['ref'], h.applied_workitem)
72
+
73
+ value = key2 if ( ! @h['participant']) && (key2 != key)
74
+ end
75
+
76
+ if value.is_a?(Array) && value.size == 2 && value.last.is_a?(Hash)
77
+ #
78
+ # participant 'defined' in var
79
+
80
+ @h['participant'] = value
81
+ end
82
+
83
+ unless value || @h['participant']
84
+ #
85
+ # unknown participant or subprocess
86
+
87
+ @h['state'] = 'failed'
88
+ persist_or_raise
89
+
90
+ raise("unknown participant or subprocess '#{tree[1]['ref']}'")
91
+ end
92
+
93
+ new_exp = if @h['participant']
94
+
95
+ @h['participant'] = nil if @h['participant'].respond_to?(:consume)
96
+ # instantiated participant
97
+
98
+ tree[0] = 'participant'
99
+ @h['name'] = 'participant'
100
+ Ruote::Exp::ParticipantExpression.new(@context, @h)
101
+ else
102
+
103
+ tree[0] = 'subprocess'
104
+ @h['name'] = 'subprocess'
105
+ Ruote::Exp::SubprocessExpression.new(@context, @h)
106
+ end
107
+
108
+ do_schedule_timeout(attribute(:timeout)) if tree[0] == 'subprocess'
109
+ #
110
+ # since ref neutralizes consider_timeout because participant expressions
111
+ # handle timeout by themselves, we have to force timeout consideration
112
+ # for subprocess expressions
113
+
114
+ #new_exp.initial_persist
115
+ # not necessary
116
+
117
+ new_exp.apply
118
+ end
119
+
120
+ def consider_timeout
121
+
122
+ # neutralized
123
+ end
124
+ end
125
+ end
126
+
@@ -22,7 +22,7 @@
22
22
  # Made in Japan.
23
23
  #++
24
24
 
25
- require 'ruote/subprocess'
25
+ require 'ruote/util/subprocess'
26
26
 
27
27
 
28
28
  module Ruote::Exp
@@ -153,6 +153,8 @@ module Ruote::Exp
153
153
 
154
154
  def apply
155
155
 
156
+ return invoke_engine_participant if attribute(:engine)
157
+
156
158
  ref = attribute(:ref) || attribute_text
157
159
 
158
160
  raise "no subprocess referred in #{tree}" unless ref
@@ -165,6 +167,23 @@ module Ruote::Exp
165
167
 
166
168
  launch_sub(pos, subtree, :variables => vars)
167
169
  end
170
+
171
+ protected
172
+
173
+ def invoke_engine_participant
174
+
175
+ atts = tree[1]
176
+
177
+ if ref = atts.find { |k, v| v.nil? }
178
+ ref = ref.first
179
+ atts.delete(ref)
180
+ end
181
+ atts['pdef'] = atts['ref'] || ref
182
+ atts['ref'] = atts.delete('engine')
183
+
184
+ @h['name'] = 'participant'
185
+ Ruote::Exp::ParticipantExpression.new(@context, @h).apply
186
+ end
168
187
  end
169
188
  end
170
189
 
@@ -42,7 +42,10 @@ module Ruote::Exp
42
42
  #
43
43
  # == :for and :until
44
44
  #
45
- # TODO
45
+ # 'wait' accepts as well :
46
+ #
47
+ # wait :for => '30d' # wait for 30 days
48
+ # wait :until => '2011/12/10 12:00:00' # any parseable date/time format
46
49
  #
47
50
  class WaitExpression < FlowExpression
48
51
 
@@ -96,16 +96,13 @@ module Ruote::Exp
96
96
  # As said, the default 'check' frequency is 10 seconds. This can be changed
97
97
  # by using the :frequency (or :freq) attribute.
98
98
  #
99
- # sequence do
100
- #
101
- # participant 'logistic_unit'
102
- #
103
- # _when '${v:/delivery_ok}', :frequency => '2d'
104
- # # block until delivery is OK (another branch of the process probably)
105
- # # check every two days
106
- #
107
- # participant 'accounting_unit'
108
- # end
99
+ # sequence do
100
+ # participant 'logistic_unit'
101
+ # _when '${v:/delivery_ok}', :frequency => '2d'
102
+ # # block until delivery is OK (another branch of the process probably)
103
+ # # check every two days
104
+ # participant 'accounting_unit'
105
+ # end
109
106
  #
110
107
  #
111
108
  # == :frequency and cron notation
@@ -24,7 +24,6 @@
24
24
 
25
25
  require 'ruote/util/time'
26
26
  require 'ruote/util/ometa'
27
- require 'ruote/util/dollar'
28
27
  require 'ruote/util/hashdot'
29
28
 
30
29
 
@@ -120,7 +119,7 @@ module Ruote::Exp
120
119
  end
121
120
 
122
121
  # Turns this FlowExpression instance into a Hash (well, just hands back
123
- # the base hash behind it.
122
+ # the base hash behind it).
124
123
  #
125
124
  def to_h
126
125
 
@@ -169,17 +168,25 @@ module Ruote::Exp
169
168
  action = msg['action']
170
169
 
171
170
  if action == 'reply' && fei['engine_id'] != context.engine_id
171
+ #
172
+ # the reply has to go to another engine, let's locate the
173
+ # 'engine participant' and give it the workitem/reply
174
+ #
175
+ # see ft_37 for a test/example
172
176
 
173
- ep = context.plist.lookup(fei['engine_id'])
177
+ engine_participant =
178
+ context.plist.lookup(fei['engine_id'], msg['workitem'])
174
179
 
175
180
  raise(
176
181
  "no EngineParticipant found under name '#{fei['engine_id']}'"
177
- ) unless ep
182
+ ) unless engine_participant
178
183
 
179
- ep.reply(fei, msg['workitem'])
184
+ engine_participant.reply(fei, msg['workitem'])
180
185
  return
181
186
  end
182
187
 
188
+ # normal case
189
+
183
190
  fexp = nil
184
191
 
185
192
  3.times do
@@ -240,6 +247,10 @@ module Ruote::Exp
240
247
 
241
248
  trigger('on_cancel', workitem)
242
249
 
250
+ elsif (h.state == 'cancelling') and h.on_re_apply
251
+
252
+ trigger('on_re_apply', workitem)
253
+
243
254
  elsif (h.state == 'timing_out') and h.on_timeout
244
255
 
245
256
  trigger('on_timeout', workitem)
@@ -346,7 +357,9 @@ module Ruote::Exp
346
357
  elsif hra = msg['re_apply']
347
358
 
348
359
  hra = {} if hra == true
349
- h.on_cancel = hra['tree'] || tree
360
+
361
+ h.on_re_apply = hra['tree'] || tree
362
+
350
363
  if fs = hra['fields']
351
364
  h.applied_workitem['fields'] = fs
352
365
  end
@@ -512,7 +525,7 @@ module Ruote::Exp
512
525
  workitem = msg['workitem']
513
526
 
514
527
  workitem['fields']['__error__'] = [
515
- h.fei, Ruote.now_to_utc_s, error.class.to_s, error.message ]
528
+ h.fei, Ruote.now_to_utc_s, error.class.to_s, error.message, error.backtrace ]
516
529
 
517
530
  @context.storage.put_msg(
518
531
  'fail',
@@ -656,7 +669,7 @@ module Ruote::Exp
656
669
  end
657
670
  end
658
671
 
659
- # Called by do_apply. Overriden in ParticipantExpression.
672
+ # Called by do_apply. Overriden in ParticipantExpression and RefExpression.
660
673
  #
661
674
  def consider_timeout
662
675
 
@@ -669,9 +682,7 @@ module Ruote::Exp
669
682
  def do_schedule_timeout (timeout)
670
683
 
671
684
  return unless timeout
672
-
673
- #h.timeout_at = Ruote.s_to_at(timeout)
674
- #return if not(h.timeout_at) || h.timeout_at < Time.now.utc + 1.0
685
+ return if timeout.strip == ''
675
686
 
676
687
  h.timeout_schedule_id = @context.storage.put_schedule(
677
688
  'at',
@@ -711,7 +722,7 @@ module Ruote::Exp
711
722
  }.merge!(opts))
712
723
  end
713
724
 
714
- # 'on_{error|timeout|cancel}' triggering
725
+ # 'on_{error|timeout|cancel|re_apply}' triggering
715
726
  #
716
727
  def trigger (on, workitem)
717
728
 
@@ -60,7 +60,7 @@ module Ruote::Exp
60
60
  elsif escape
61
61
  v
62
62
  else
63
- Ruote.dosub(v, self, workitem)
63
+ @context.dollar_sub.s(v, self, workitem)
64
64
  end
65
65
 
66
66
  v = v.to_s if v and string
@@ -130,7 +130,7 @@ module Ruote::Exp
130
130
  def expand_atts (opts={})
131
131
 
132
132
  attributes.keys.inject({}) { |r, k|
133
- kk = Ruote.dosub(k, self, h.applied_workitem)
133
+ kk = @context.dollar_sub.s(k, self, h.applied_workitem)
134
134
  r[kk] = attribute(k, h.applied_workitem, opts)
135
135
  r
136
136
  }
@@ -152,7 +152,7 @@ module Ruote::Exp
152
152
 
153
153
  text = attributes.keys.find { |k| attributes[k] == nil }
154
154
 
155
- Ruote.dosub(text.to_s, self, workitem)
155
+ @context.dollar_sub.s(text.to_s, self, workitem)
156
156
  end
157
157
 
158
158
  protected
@@ -163,6 +163,8 @@ module Ruote::Exp
163
163
  attribute(:to_f) || attribute(:to_fld) || attribute(:to_field) ]
164
164
  end
165
165
 
166
+ # Val and Value (Sense and Sensibility ?)
167
+ #
166
168
  VV = %w[ val value ]
167
169
 
168
170
  def s_cartesian (a0, a1)
@@ -183,11 +185,6 @@ module Ruote::Exp
183
185
 
184
186
  elsif k = has_att(*flds)
185
187
 
186
- #k = attribute(k, @applied_workitem, att_options)
187
-
188
- #@applied_workitem.attributes[k.to_s] ||
189
- #@applied_workitem.attributes[k.to_s.to_sym]
190
-
191
188
  k = attribute(k, h.applied_workitem, att_options)
192
189
  h.applied_workitem['fields'][k]
193
190
 
@@ -50,7 +50,7 @@ module Ruote::Exp
50
50
  end
51
51
 
52
52
  # Looks up the value of a variable in expression tree
53
- # (seen from a leave, it looks more like a stack than a tree)
53
+ # (seen from a leaf, it looks more like a stack than a tree)
54
54
  #
55
55
  def lookup_variable (var, prefix=nil)
56
56
 
@@ -118,7 +118,9 @@ module Ruote::Exp
118
118
  fexp.un_set_variable(:unset, v, nil, should_persist)
119
119
  end
120
120
 
121
- # This method is mostly used by the expression pool when looking up
121
+ # TODO : redoc rewrite needed
122
+ #
123
+ # This method is mostly used by the worker when looking up
122
124
  # a process name or participant name bound under a variable.
123
125
  #
124
126
  def iterative_var_lookup (k)
data/lib/ruote/fei.rb CHANGED
@@ -96,6 +96,8 @@ module Ruote
96
96
  "#{@h['expid']}!#{@h['sub_wfid']}!#{@h['wfid']}"
97
97
  end
98
98
 
99
+ alias sid to_storage_id
100
+
99
101
  def self.to_storage_id (hfei)
100
102
 
101
103
  hfei.respond_to?(:to_storage_id) ?
@@ -50,7 +50,7 @@ module Ruote
50
50
  lraw = @last['raw'] + 0.01
51
51
 
52
52
  raw = Time.now.utc
53
- while raw.to_f <= lraw; raw = raw + 0.01; end
53
+ raw = raw + 0.01 while raw.to_f <= lraw
54
54
 
55
55
  @last['raw'] = raw.to_f
56
56
 
@@ -0,0 +1,137 @@
1
+ #--
2
+ # Copyright (c) 2005-2010, 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 container for the pretty printing logic of TestLogger.
30
+ #
31
+ module PrettyLogging
32
+
33
+ protected
34
+
35
+ #--
36
+ # <ESC>[{attr1};...;{attrn}m
37
+ #
38
+ # 0 Reset all attributes
39
+ # 1 Bright
40
+ # 2 Dim
41
+ # 4 Underscore
42
+ # 5 Blink
43
+ # 7 Reverse
44
+ # 8 Hidden
45
+ #
46
+ # Foreground Colours
47
+ # 30 Black
48
+ # 31 Red
49
+ # 32 Green
50
+ # 33 Yellow
51
+ # 34 Blue
52
+ # 35 Magenta
53
+ # 36 Cyan
54
+ # 37 White
55
+ #
56
+ # Background Colours
57
+ # 40 Black
58
+ # 41 Red
59
+ # 42 Green
60
+ # 43 Yellow
61
+ # 44 Blue
62
+ # 45 Magenta
63
+ # 46 Cyan
64
+ # 47 White
65
+ #++
66
+
67
+ def color (mod, s, clear=false)
68
+
69
+ return s if Ruote::WIN
70
+ return s unless STDOUT.tty?
71
+
72
+ "[#{mod}m#{s}#{clear ? '' : "[#{@color}m"}"
73
+ end
74
+
75
+ def pretty_print (msg)
76
+
77
+ @count += 1
78
+ @count = 0 if @count > 9
79
+
80
+ ei = self.object_id.to_s[-2..-1]
81
+
82
+ fei = msg['fei']
83
+ depth = fei ? fei['expid'].split('_').size : 0
84
+
85
+ i = fei ?
86
+ [ fei['wfid'], fei['sub_wfid'], fei['expid'] ].join(' ') :
87
+ msg['wfid']
88
+
89
+ rest = msg.dup
90
+ %w[
91
+ _id put_at _rev
92
+ type action
93
+ fei wfid variables
94
+ ].each { |k| rest.delete(k) }
95
+
96
+ if v = rest['parent_id']
97
+ rest['parent_id'] = Ruote.to_storage_id(v)
98
+ end
99
+ if v = rest.delete('workitem')
100
+ rest[:wi] = [
101
+ v['fei'] ? Ruote.to_storage_id(v['fei']) : nil,
102
+ v['fields'].size ]
103
+ end
104
+
105
+ { 'tree' => :t, 'parent_id' => :pi }.each do |k0, k1|
106
+ if v = rest.delete(k0)
107
+ rest[k1] = v
108
+ end
109
+ end
110
+
111
+ action = msg['action'][0, 2]
112
+ action = case msg['action']
113
+ when 'receive' then 'rc'
114
+ when 'dispatched' then 'dd'
115
+ when 'dispatch_cancel' then 'dc'
116
+ else action
117
+ end
118
+ action = case action
119
+ when 'la' then color('4;32', action)
120
+ when 'te' then color('4;31', action)
121
+ when 'ce' then color('31', action)
122
+ when 'ca' then color('31', action)
123
+ when 'rc' then color('4;33', action)
124
+ when 'di' then color('4;33', action)
125
+ when 'dd' then color('4;33', action)
126
+ when 'dc' then color('4;31', action)
127
+ else action
128
+ end
129
+
130
+ color(
131
+ @color,
132
+ "#{@count} #{ei} #{' ' * depth}#{action} * #{i} #{rest.inspect}",
133
+ true)
134
+ end
135
+ end
136
+ end
137
+