ruote 2.1.10 → 2.1.11

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