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
@@ -22,13 +22,15 @@
|
|
22
22
|
# Made in Japan.
|
23
23
|
#++
|
24
24
|
|
25
|
-
|
25
|
+
require 'ruote/log/pretty'
|
26
26
|
|
27
27
|
|
28
28
|
module Ruote
|
29
29
|
|
30
30
|
class TestLogger
|
31
31
|
|
32
|
+
include PrettyLogging
|
33
|
+
|
32
34
|
attr_reader :seen
|
33
35
|
attr_reader :log
|
34
36
|
|
@@ -52,20 +54,15 @@ module Ruote
|
|
52
54
|
|
53
55
|
@seen = []
|
54
56
|
@log = []
|
55
|
-
@waiting =
|
57
|
+
@waiting = []
|
56
58
|
|
57
59
|
@count = -1
|
58
60
|
@color = 33
|
59
61
|
@noisy = false
|
60
|
-
|
61
|
-
# NOTE
|
62
|
-
# in case of troubles, why not have the wait_for has an event ?
|
63
62
|
end
|
64
63
|
|
65
64
|
def notify (msg)
|
66
65
|
|
67
|
-
#@context.storage.put(event.merge('type' => 'archived_msgs'))
|
68
|
-
|
69
66
|
puts(pretty_print(msg)) if @noisy
|
70
67
|
|
71
68
|
@seen << msg
|
@@ -74,13 +71,26 @@ module Ruote
|
|
74
71
|
check_waiting
|
75
72
|
end
|
76
73
|
|
74
|
+
# Blocks until one or more interests are satisfied.
|
75
|
+
#
|
76
|
+
# interests must be an array of interests. Please refer to
|
77
|
+
# Engine#wait_for documentation for allowed values of each interest.
|
78
|
+
#
|
79
|
+
# If multiple interests are given, wait_for blocks until
|
80
|
+
# all of the interests are satisfied.
|
81
|
+
#
|
82
|
+
# wait_for may only be used by one thread at a time. If one
|
83
|
+
# thread calls wait_for and later another thread calls wait_for
|
84
|
+
# while the first thread is waiting, the first thread's
|
85
|
+
# interests are lost and the first thread will never wake up.
|
86
|
+
#
|
77
87
|
def wait_for (interests)
|
78
88
|
|
79
|
-
@waiting
|
89
|
+
@waiting << [ Thread.current, interests ]
|
80
90
|
|
81
91
|
check_waiting
|
82
92
|
|
83
|
-
Thread.stop if @waiting
|
93
|
+
Thread.stop if @waiting.find { |w| w.first == Thread.current }
|
84
94
|
|
85
95
|
# and when this thread gets woken up, go on and return __result__
|
86
96
|
|
@@ -109,39 +119,52 @@ module Ruote
|
|
109
119
|
|
110
120
|
def check_waiting
|
111
121
|
|
112
|
-
return
|
122
|
+
return if @waiting.size < 1
|
113
123
|
|
114
124
|
while msg = @seen.shift
|
115
|
-
|
116
|
-
break if check_msg(msg)
|
125
|
+
check_msg(msg)
|
117
126
|
end
|
118
127
|
end
|
119
128
|
|
120
129
|
def check_msg (msg)
|
121
130
|
|
122
|
-
|
131
|
+
wakeup = []
|
123
132
|
|
124
|
-
|
125
|
-
@waiting = nil
|
126
|
-
thread['__result__'] = msg
|
127
|
-
thread.wakeup
|
133
|
+
@waiting.each do |thread, interests|
|
128
134
|
|
129
|
-
|
130
|
-
|
135
|
+
wakeup << thread if matches(interests, msg)
|
136
|
+
end
|
131
137
|
|
132
|
-
|
138
|
+
@waiting.delete_if { |t, i| i.size < 1 }
|
139
|
+
|
140
|
+
wakeup.each do |thread|
|
141
|
+
|
142
|
+
thread['__result__'] = msg
|
143
|
+
thread.wakeup
|
133
144
|
end
|
134
145
|
end
|
135
146
|
|
136
147
|
FINAL_ACTIONS = %w[ terminated ceased error_intercepted ]
|
137
148
|
|
138
|
-
|
149
|
+
# Checks whether message msg matches any of interests being waited for.
|
150
|
+
#
|
151
|
+
# Some interests look for actions on particular workflows (e.g.,
|
152
|
+
# waiting for some workflow to finish). Other interests are not
|
153
|
+
# attached to any particular workflow (e.g., :inactive waits until
|
154
|
+
# the engine finishes processing all active and pending workflows)
|
155
|
+
# but are still satisfied when actions happen on workflows (e.g.,
|
156
|
+
# the last workflow being run finishes).
|
157
|
+
#
|
158
|
+
# Returns true if all interests being waited for have been satisfied,
|
159
|
+
# false otherwise.
|
160
|
+
#
|
161
|
+
def matches (interests, msg)
|
139
162
|
|
140
163
|
action = msg['action']
|
141
164
|
|
142
|
-
|
165
|
+
interests.each do |interest|
|
143
166
|
|
144
|
-
satisfied =
|
167
|
+
satisfied = if interest == :inactive
|
145
168
|
|
146
169
|
(FINAL_ACTIONS.include?(action) && @context.worker.inactive?)
|
147
170
|
|
@@ -155,9 +178,10 @@ module Ruote
|
|
155
178
|
|
156
179
|
elsif interest.is_a?(Fixnum)
|
157
180
|
|
158
|
-
|
181
|
+
interests.delete(interest)
|
182
|
+
|
159
183
|
if (interest > 1)
|
160
|
-
|
184
|
+
interests << (interest - 1)
|
161
185
|
false
|
162
186
|
else
|
163
187
|
true
|
@@ -168,109 +192,10 @@ module Ruote
|
|
168
192
|
(FINAL_ACTIONS.include?(action) && msg['wfid'] == interest)
|
169
193
|
end
|
170
194
|
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
@waiting.last.size < 1
|
175
|
-
end
|
176
|
-
|
177
|
-
# <ESC>[{attr1};...;{attrn}m
|
178
|
-
#
|
179
|
-
# 0 Reset all attributes
|
180
|
-
# 1 Bright
|
181
|
-
# 2 Dim
|
182
|
-
# 4 Underscore
|
183
|
-
# 5 Blink
|
184
|
-
# 7 Reverse
|
185
|
-
# 8 Hidden
|
186
|
-
#
|
187
|
-
# Foreground Colours
|
188
|
-
# 30 Black
|
189
|
-
# 31 Red
|
190
|
-
# 32 Green
|
191
|
-
# 33 Yellow
|
192
|
-
# 34 Blue
|
193
|
-
# 35 Magenta
|
194
|
-
# 36 Cyan
|
195
|
-
# 37 White
|
196
|
-
#
|
197
|
-
# Background Colours
|
198
|
-
# 40 Black
|
199
|
-
# 41 Red
|
200
|
-
# 42 Green
|
201
|
-
# 43 Yellow
|
202
|
-
# 44 Blue
|
203
|
-
# 45 Magenta
|
204
|
-
# 46 Cyan
|
205
|
-
# 47 White
|
206
|
-
|
207
|
-
def color (mod, s, clear=false)
|
208
|
-
|
209
|
-
return s if Ruote::WIN
|
210
|
-
return s unless STDOUT.tty?
|
211
|
-
|
212
|
-
"[#{mod}m#{s}[0m#{clear ? '' : "[#{@color}m"}"
|
213
|
-
end
|
214
|
-
|
215
|
-
def pretty_print (msg)
|
216
|
-
|
217
|
-
@count += 1
|
218
|
-
@count = 0 if @count > 9
|
219
|
-
|
220
|
-
ei = self.object_id.to_s[-2..-1]
|
221
|
-
|
222
|
-
fei = msg['fei']
|
223
|
-
depth = fei ? fei['expid'].split('_').size : 0
|
224
|
-
|
225
|
-
i = fei ?
|
226
|
-
[ fei['wfid'], fei['sub_wfid'], fei['expid'] ].join(' ') :
|
227
|
-
msg['wfid']
|
228
|
-
|
229
|
-
rest = msg.dup
|
230
|
-
%w[
|
231
|
-
_id put_at _rev
|
232
|
-
type action
|
233
|
-
fei wfid variables
|
234
|
-
].each { |k| rest.delete(k) }
|
235
|
-
|
236
|
-
if v = rest['parent_id']
|
237
|
-
rest['parent_id'] = Ruote.to_storage_id(v)
|
238
|
-
end
|
239
|
-
if v = rest.delete('workitem')
|
240
|
-
rest[:wi] = [
|
241
|
-
v['fei'] ? Ruote.to_storage_id(v['fei']) : nil,
|
242
|
-
v['fields'].size ]
|
243
|
-
end
|
244
|
-
|
245
|
-
{ 'tree' => :t, 'parent_id' => :pi }.each do |k0, k1|
|
246
|
-
if v = rest.delete(k0)
|
247
|
-
rest[k1] = v
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
action = msg['action'][0, 2]
|
252
|
-
action = case msg['action']
|
253
|
-
when 'receive' then 'rc'
|
254
|
-
when 'dispatched' then 'dd'
|
255
|
-
when 'dispatch_cancel' then 'dc'
|
256
|
-
else action
|
257
|
-
end
|
258
|
-
action = case action
|
259
|
-
when 'la' then color('4;32', action)
|
260
|
-
when 'te' then color('4;31', action)
|
261
|
-
when 'ce' then color('31', action)
|
262
|
-
when 'ca' then color('31', action)
|
263
|
-
when 'rc' then color('4;33', action)
|
264
|
-
when 'di' then color('4;33', action)
|
265
|
-
when 'dd' then color('4;33', action)
|
266
|
-
when 'dc' then color('4;31', action)
|
267
|
-
else action
|
195
|
+
interests.delete(interest) if satisfied
|
268
196
|
end
|
269
197
|
|
270
|
-
|
271
|
-
@color,
|
272
|
-
"#{@count} #{ei} #{' ' * depth}#{action} * #{i} #{rest.inspect}",
|
273
|
-
true)
|
198
|
+
interests.size < 1
|
274
199
|
end
|
275
200
|
end
|
276
201
|
end
|
@@ -37,33 +37,28 @@ module Ruote
|
|
37
37
|
def initialize (context)
|
38
38
|
|
39
39
|
@context = context
|
40
|
-
@waiting = nil
|
41
40
|
@color = 33
|
42
41
|
|
43
42
|
@context.worker.subscribe(:all, self) if @context.worker
|
44
43
|
|
45
44
|
@noisy = false
|
46
45
|
@count = -1
|
46
|
+
|
47
|
+
@seen = []
|
48
|
+
@waiting = []
|
47
49
|
end
|
48
50
|
|
49
51
|
def notify (msg)
|
50
52
|
|
51
53
|
puts(pretty_print(msg)) if @noisy
|
52
54
|
|
53
|
-
return
|
54
|
-
|
55
|
-
check_msg(msg)
|
56
|
-
end
|
57
|
-
|
58
|
-
def wait_for (interests)
|
59
|
-
|
60
|
-
@waiting = [ Thread.current, interests ]
|
61
|
-
|
62
|
-
Thread.stop
|
55
|
+
#return if @waiting.size < 1
|
56
|
+
#check_msg(msg)
|
63
57
|
|
64
|
-
|
58
|
+
@seen << msg
|
59
|
+
@seen.shift if @seen.size > 147
|
65
60
|
|
66
|
-
|
61
|
+
check_waiting
|
67
62
|
end
|
68
63
|
end
|
69
64
|
end
|
@@ -22,6 +22,8 @@
|
|
22
22
|
# Made in Japan.
|
23
23
|
#++
|
24
24
|
|
25
|
+
require 'ruote/util/ometa'
|
26
|
+
|
25
27
|
|
26
28
|
module Ruote
|
27
29
|
|
@@ -94,7 +96,7 @@ module Ruote
|
|
94
96
|
#
|
95
97
|
module RubyDsl
|
96
98
|
|
97
|
-
class BranchContext
|
99
|
+
class BranchContext < Ruote::BlankSlate
|
98
100
|
|
99
101
|
def initialize (name, attributes)
|
100
102
|
|
@@ -117,9 +119,7 @@ module Ruote
|
|
117
119
|
|
118
120
|
def self.create_branch (name, attributes, &block)
|
119
121
|
|
120
|
-
while name[0, 1] == '_'
|
121
|
-
name = name[1..-1]
|
122
|
-
end
|
122
|
+
name = name[1..-1] while name[0, 1] == '_'
|
123
123
|
|
124
124
|
h = attributes.inject({}) { |h1, a|
|
125
125
|
a.is_a?(Hash) ? h1.merge!(a) : h1[a] = nil
|
data/lib/ruote/parser.rb
CHANGED
@@ -55,7 +55,7 @@ module Ruote
|
|
55
55
|
(return Rufus::Json.decode(definition)) rescue nil
|
56
56
|
(return ruby_eval(definition)) rescue nil
|
57
57
|
|
58
|
-
if definition.index("\n")
|
58
|
+
if definition.index("\n").nil? && definition.index(' ').nil?
|
59
59
|
|
60
60
|
raise ArgumentError.new(
|
61
61
|
"remote process definitions are not allowed"
|
@@ -77,7 +77,7 @@ module Ruote
|
|
77
77
|
unless @parser
|
78
78
|
|
79
79
|
require 'ostruct'
|
80
|
-
require 'ruote/
|
80
|
+
require 'ruote/svc/treechecker'
|
81
81
|
|
82
82
|
@parser = Ruote::Parser.new(
|
83
83
|
OpenStruct.new('treechecker' => Ruote::TreeChecker.new({})))
|
@@ -138,7 +138,7 @@ module Ruote
|
|
138
138
|
#
|
139
139
|
def size
|
140
140
|
|
141
|
-
fetch_all
|
141
|
+
fetch_all(:count => true)
|
142
142
|
end
|
143
143
|
|
144
144
|
# Iterates over the workitems stored in here.
|
@@ -150,9 +150,9 @@ module Ruote
|
|
150
150
|
|
151
151
|
# Returns all the workitems stored in here.
|
152
152
|
#
|
153
|
-
def all
|
153
|
+
def all (opts={})
|
154
154
|
|
155
|
-
fetch_all.map { |hwi| Ruote::Workitem.new(hwi) }
|
155
|
+
fetch_all(opts).map { |hwi| Ruote::Workitem.new(hwi) }
|
156
156
|
end
|
157
157
|
|
158
158
|
# A convenience method (especially when testing), returns the first
|
@@ -169,22 +169,24 @@ module Ruote
|
|
169
169
|
#
|
170
170
|
def by_wfid (wfid)
|
171
171
|
|
172
|
-
@context.storage.get_many('workitems',
|
172
|
+
@context.storage.get_many('workitems', wfid).collect { |hwi|
|
173
173
|
Ruote::Workitem.new(hwi)
|
174
174
|
}
|
175
175
|
end
|
176
176
|
|
177
177
|
# Returns all workitems for the specified participant name
|
178
178
|
#
|
179
|
-
def by_participant (participant_name)
|
179
|
+
def by_participant (participant_name, opts={})
|
180
180
|
|
181
181
|
hwis = if @context.storage.respond_to?(:by_participant)
|
182
182
|
|
183
|
-
@context.storage.by_participant('workitems', participant_name)
|
183
|
+
@context.storage.by_participant('workitems', participant_name, opts)
|
184
184
|
|
185
185
|
else
|
186
186
|
|
187
|
-
fetch_all.select { |wi|
|
187
|
+
fetch_all(opts).select { |wi|
|
188
|
+
wi['participant_name'] == participant_name
|
189
|
+
}
|
188
190
|
end
|
189
191
|
|
190
192
|
hwis.collect { |hwi| Ruote::Workitem.new(hwi) }
|
@@ -230,7 +232,7 @@ module Ruote
|
|
230
232
|
# constraints for fields.
|
231
233
|
#
|
232
234
|
# 'offset' and 'limit' are reserved as well. They should prove useful
|
233
|
-
# for pagination.
|
235
|
+
# for pagination. 'skip' can be used instead of 'offset'.
|
234
236
|
#
|
235
237
|
# Note : the criteria is AND only, you'll have to do ORs (aggregation)
|
236
238
|
# by yourself.
|
@@ -239,32 +241,28 @@ module Ruote
|
|
239
241
|
|
240
242
|
cr = criteria.inject({}) { |h, (k, v)| h[k.to_s] = v; h }
|
241
243
|
|
242
|
-
|
243
|
-
|
244
|
-
|
244
|
+
if @context.storage.respond_to?(:query_workitems)
|
245
|
+
return @context.storage.query_workitems(cr)
|
246
|
+
end
|
245
247
|
|
246
|
-
|
247
|
-
|
248
|
+
opts = {}
|
249
|
+
opts[:skip] = cr.delete('offset') || cr.delete('skip')
|
250
|
+
opts[:limit] = cr.delete('limit')
|
251
|
+
opts[:count] = cr.delete('count')
|
248
252
|
|
249
253
|
wfid = cr.delete('wfid')
|
250
254
|
pname = cr.delete('participant_name') || cr.delete('participant')
|
251
255
|
|
252
|
-
hwis =
|
253
|
-
@context.storage.get_many('workitems',
|
254
|
-
else
|
255
|
-
fetch_all
|
256
|
-
end
|
256
|
+
hwis = wfid ?
|
257
|
+
@context.storage.get_many('workitems', wfid, opts) : fetch_all(opts)
|
257
258
|
|
258
|
-
|
259
|
+
return hwis if opts[:count]
|
260
|
+
|
261
|
+
hwis.select { |hwi|
|
259
262
|
Ruote::StorageParticipant.matches?(hwi, pname, cr)
|
260
263
|
}.collect { |hwi|
|
261
264
|
Ruote::Workitem.new(hwi)
|
262
265
|
}
|
263
|
-
|
264
|
-
offset = offset || 0
|
265
|
-
limit = limit || hwis.length
|
266
|
-
|
267
|
-
hwis[offset, limit]
|
268
266
|
end
|
269
267
|
|
270
268
|
# Cleans this participant out completely
|
@@ -294,11 +292,12 @@ module Ruote
|
|
294
292
|
# Fetches all the workitems. If there is a @store_name, will only fetch
|
295
293
|
# the workitems in that store.
|
296
294
|
#
|
297
|
-
def fetch_all
|
298
|
-
|
299
|
-
key = @store_name ? /^wi!#{@store_name}::/ : nil
|
295
|
+
def fetch_all (opts={})
|
300
296
|
|
301
|
-
@context.storage.get_many(
|
297
|
+
@context.storage.get_many(
|
298
|
+
'workitems',
|
299
|
+
@store_name ? /^wi!#{@store_name}::/ : nil,
|
300
|
+
opts)
|
302
301
|
end
|
303
302
|
|
304
303
|
# Computes the id for the document representing the document in the storage.
|
data/lib/ruote/part/template.rb
CHANGED
@@ -23,7 +23,6 @@
|
|
23
23
|
#++
|
24
24
|
|
25
25
|
require 'rufus/json'
|
26
|
-
require 'ruote/util/dollar'
|
27
26
|
|
28
27
|
|
29
28
|
module Ruote
|
@@ -34,8 +33,14 @@ module Ruote
|
|
34
33
|
# (Currently only used by the SmtpParticipant, could prove useful for
|
35
34
|
# custom participants)
|
36
35
|
#
|
36
|
+
# This module expects to find the ruote @context available (probably
|
37
|
+
# accessible thanks to the Ruote::LocalParticipant module, see
|
38
|
+
# Ruote::SmtpParticipant as an example).
|
39
|
+
#
|
37
40
|
module TemplateMixin
|
38
41
|
|
42
|
+
# Do the rendering.
|
43
|
+
#
|
39
44
|
def render_template (template, flow_expression, workitem)
|
40
45
|
|
41
46
|
template = (File.read(template) rescue nil) if is_a_file?(template)
|
@@ -45,7 +50,7 @@ module Ruote
|
|
45
50
|
template = template.to_s
|
46
51
|
workitem = workitem.to_h if workitem.respond_to?(:to_h)
|
47
52
|
|
48
|
-
|
53
|
+
@context.dollar_sub.s(template, flow_expression, workitem)
|
49
54
|
end
|
50
55
|
|
51
56
|
# Simply returns a pretty-printed view of the workitem
|
@@ -57,7 +62,7 @@ module Ruote
|
|
57
62
|
s = []
|
58
63
|
s << "workitem for #{workitem['participant_name']}"
|
59
64
|
s << ''
|
60
|
-
s << Rufus::Json.
|
65
|
+
s << Rufus::Json.pretty_encode(workitem['fei'])
|
61
66
|
s << ''
|
62
67
|
workitem['fields'].keys.sort.each do |key|
|
63
68
|
s << " - '#{key}' ==> #{Rufus::Json.encode(workitem['fields'][key])}"
|
data/lib/ruote/receiver/base.rb
CHANGED
@@ -55,6 +55,14 @@ module Ruote
|
|
55
55
|
# This method is mostly used from the Ruote::Engine class (which includes
|
56
56
|
# this mixin).
|
57
57
|
#
|
58
|
+
# process_definition must be a result of Ruote.process_definition call
|
59
|
+
# or XML or JSON serialized process definition, as accepted by
|
60
|
+
# Ruote::Parser#parse.
|
61
|
+
#
|
62
|
+
# fields are workflow parameters that will be placed in workitem.fields.
|
63
|
+
#
|
64
|
+
# variables contain engine variables.
|
65
|
+
#
|
58
66
|
def launch (process_definition, fields={}, variables={})
|
59
67
|
|
60
68
|
wfid = @context.wfidgen.generate
|
@@ -98,16 +106,26 @@ module Ruote
|
|
98
106
|
self.class.to_s
|
99
107
|
end
|
100
108
|
|
101
|
-
|
102
|
-
|
103
|
-
# Convenience method, fetches the flow expression (ParticipantExpression)
|
104
|
-
# that emitted that workitem.
|
109
|
+
# Convenience method, given a workitem or a fei, returns the
|
110
|
+
# corresponding flow expession.
|
105
111
|
#
|
106
|
-
def fetch_flow_expression (
|
112
|
+
def fetch_flow_expression (workitem_or_fei)
|
107
113
|
|
108
|
-
Ruote::Exp::FlowExpression.fetch(
|
114
|
+
Ruote::Exp::FlowExpression.fetch(
|
115
|
+
@context,
|
116
|
+
Ruote::FlowExpressionId.extract_h(workitem_or_fei))
|
109
117
|
end
|
110
118
|
|
119
|
+
# For example :
|
120
|
+
#
|
121
|
+
# fexp = engine.fexp(fei)
|
122
|
+
# # or
|
123
|
+
# fexp = engine.fexp(workitem)
|
124
|
+
#
|
125
|
+
alias fexp fetch_flow_expression
|
126
|
+
|
127
|
+
protected
|
128
|
+
|
111
129
|
# Stashes values in the participant expression (in the storage).
|
112
130
|
#
|
113
131
|
# put(workitem.fei, 'key' => 'value', 'colour' => 'blue')
|