ruote 2.1.10 → 2.1.11
Sign up to get free protection for your applications and to get access to all the features.
- 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')
|