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.
- data/CHANGELOG.txt +51 -1
- data/CREDITS.txt +9 -0
- data/README.rdoc +13 -0
- data/Rakefile +50 -21
- data/TODO.txt +42 -4
- data/examples/pong.rb +37 -0
- data/lib/ruote/context.rb +19 -9
- data/lib/ruote/engine/process_error.rb +10 -0
- data/lib/ruote/engine/process_status.rb +140 -41
- data/lib/ruote/engine.rb +394 -27
- data/lib/ruote/exp/command.rb +2 -0
- data/lib/ruote/exp/fe_concurrence.rb +8 -0
- data/lib/ruote/exp/fe_concurrent_iterator.rb +3 -0
- data/lib/ruote/exp/fe_cursor.rb +48 -4
- data/lib/ruote/exp/fe_iterator.rb +40 -0
- data/lib/ruote/exp/fe_listen.rb +3 -3
- data/lib/ruote/exp/fe_participant.rb +30 -12
- data/lib/ruote/exp/fe_ref.rb +126 -0
- data/lib/ruote/exp/fe_subprocess.rb +20 -1
- data/lib/ruote/exp/fe_wait.rb +4 -1
- data/lib/ruote/exp/fe_when.rb +7 -10
- data/lib/ruote/exp/flowexpression.rb +23 -12
- data/lib/ruote/exp/ro_attributes.rb +5 -8
- data/lib/ruote/exp/ro_variables.rb +4 -2
- data/lib/ruote/fei.rb +2 -0
- data/lib/ruote/id/wfid_generator.rb +1 -1
- data/lib/ruote/log/pretty.rb +137 -0
- data/lib/ruote/log/storage_history.rb +1 -1
- data/lib/ruote/log/test_logger.rb +51 -126
- data/lib/ruote/log/wait_logger.rb +8 -13
- data/lib/ruote/parser/ruby_dsl.rb +4 -4
- data/lib/ruote/parser.rb +2 -2
- data/lib/ruote/part/block_participant.rb +1 -1
- data/lib/ruote/part/engine_participant.rb +1 -1
- data/lib/ruote/part/storage_participant.rb +27 -28
- data/lib/ruote/part/template.rb +8 -3
- data/lib/ruote/receiver/base.rb +24 -6
- data/lib/ruote/storage/base.rb +76 -11
- data/lib/ruote/storage/fs_storage.rb +10 -0
- data/lib/ruote/storage/hash_storage.rb +19 -8
- data/lib/ruote/{part → svc}/dispatch_pool.rb +3 -2
- data/lib/ruote/svc/dollar_sub.rb +265 -0
- data/lib/ruote/{error_handler.rb → svc/error_handler.rb} +6 -1
- data/lib/ruote/{exp → svc}/expression_map.rb +31 -37
- data/lib/ruote/{part → svc}/participant_list.rb +165 -25
- data/lib/ruote/{evt → svc}/tracker.rb +0 -0
- data/lib/ruote/{util → svc}/treechecker.rb +0 -0
- data/lib/ruote/util/look.rb +4 -1
- data/lib/ruote/util/ometa.rb +21 -5
- data/lib/ruote/{subprocess.rb → util/subprocess.rb} +0 -0
- data/lib/ruote/version.rb +1 -1
- data/lib/ruote/worker.rb +29 -69
- data/lib/ruote/workitem.rb +28 -1
- data/ruote.gemspec +26 -22
- data/test/functional/base.rb +3 -0
- data/test/functional/concurrent_base.rb +1 -0
- data/test/functional/crunner.sh +1 -1
- data/test/functional/ct_0_concurrence.rb +6 -0
- data/test/functional/ct_1_iterator.rb +3 -0
- data/test/functional/ct_2_cancel.rb +5 -0
- data/test/functional/eft_13_iterator.rb +39 -4
- data/test/functional/eft_14_cursor.rb +39 -0
- data/test/functional/eft_30_ref.rb +140 -0
- data/test/functional/eft_3_participant.rb +25 -23
- data/test/functional/ft_10_dollar.rb +17 -1
- data/test/functional/ft_14_re_apply.rb +76 -0
- data/test/functional/ft_1_process_status.rb +170 -29
- data/test/functional/ft_20_storage_participant.rb +14 -0
- data/test/functional/ft_24_block_participants.rb +1 -1
- data/test/functional/ft_26_participant_timeout.rb +93 -0
- data/test/functional/ft_2_errors.rb +24 -17
- data/test/functional/ft_30_smtp_participant.rb +7 -2
- data/test/functional/ft_38_participant_more.rb +15 -0
- data/test/functional/ft_39_wait_for.rb +34 -1
- data/test/functional/ft_3_participant_registration.rb +270 -2
- data/test/functional/ft_40_wait_logger.rb +61 -0
- data/test/functional/ft_42_storage_copy.rb +4 -0
- data/test/functional/{ft_40_participant_on_reply.rb → ft_43_participant_on_reply.rb} +17 -0
- data/test/functional/ft_44_var_participant.rb +35 -0
- data/test/functional/ft_45_participant_accept.rb +64 -0
- data/test/functional/ft_46_launch_single.rb +49 -0
- data/test/functional/ft_5_on_error.rb +39 -1
- data/test/functional/storage_helper.rb +7 -1
- data/test/test_helper.rb +1 -1
- data/test/unit/storage.rb +105 -32
- data/test/unit/ut_0_ruby_parser.rb +31 -1
- data/test/unit/ut_16_parser.rb +20 -0
- data/test/unit/ut_19_part_template.rb +11 -1
- data/test/unit/ut_20_composite_storage.rb +1 -1
- data/test/unit/ut_4_expmap.rb +1 -1
- data/test/unit/ut_6_condition.rb +2 -2
- metadata +112 -74
- data/lib/ruote/exp/raw.rb +0 -44
- 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
|
#
|
data/lib/ruote/exp/fe_listen.rb
CHANGED
@@ -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.
|
140
|
-
h.
|
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.
|
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
|
-
|
135
|
+
raise ArgumentError.new(
|
136
|
+
"no participant name specified"
|
137
|
+
) if h.participant_name == ''
|
134
138
|
|
135
|
-
|
136
|
-
|
137
|
-
|
139
|
+
participant_info =
|
140
|
+
h.participant ||
|
141
|
+
@context.plist.lookup_info(h.participant_name, h.applied_workitem)
|
138
142
|
|
139
|
-
participant_info
|
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
|
-
|
187
|
-
|
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
|
-
|
232
|
-
|
233
|
-
|
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
|
|
data/lib/ruote/exp/fe_wait.rb
CHANGED
@@ -42,7 +42,10 @@ module Ruote::Exp
|
|
42
42
|
#
|
43
43
|
# == :for and :until
|
44
44
|
#
|
45
|
-
#
|
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
|
|
data/lib/ruote/exp/fe_when.rb
CHANGED
@@ -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
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
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
|
-
|
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
|
182
|
+
) unless engine_participant
|
178
183
|
|
179
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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
|
-
|
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
|
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
|
-
#
|
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
@@ -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}[0m#{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
|
+
|