flor 0.11.0 → 0.12.0
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.md +7 -0
- data/Makefile +3 -0
- data/lib/flor.rb +1 -1
- data/lib/flor/colours.rb +7 -3
- data/lib/flor/conf.rb +21 -15
- data/lib/flor/core/executor.rb +71 -77
- data/lib/flor/core/node.rb +6 -1
- data/lib/flor/core/procedure.rb +112 -58
- data/lib/flor/core/texecutor.rb +6 -5
- data/lib/flor/log.rb +9 -7
- data/lib/flor/migrations/0003_timer_onid_bnid.rb +35 -0
- data/lib/flor/migrations/0004_trap_bnid.rb +16 -0
- data/lib/flor/pcore/_arr.rb +2 -2
- data/lib/flor/pcore/_atom.rb +1 -1
- data/lib/flor/pcore/_att.rb +59 -13
- data/lib/flor/pcore/_happly.rb +3 -3
- data/lib/flor/pcore/_obj.rb +22 -2
- data/lib/flor/pcore/_skip.rb +2 -2
- data/lib/flor/pcore/apply.rb +1 -1
- data/lib/flor/pcore/arith.rb +1 -1
- data/lib/flor/pcore/break.rb +2 -2
- data/lib/flor/pcore/case.rb +1 -1
- data/lib/flor/pcore/cmp.rb +1 -1
- data/lib/flor/pcore/cond.rb +1 -1
- data/lib/flor/pcore/cursor.rb +2 -2
- data/lib/flor/pcore/define.rb +1 -1
- data/lib/flor/pcore/fail.rb +1 -6
- data/lib/flor/pcore/if.rb +2 -2
- data/lib/flor/pcore/map.rb +1 -1
- data/lib/flor/pcore/matchr.rb +92 -0
- data/lib/flor/pcore/move.rb +2 -3
- data/lib/flor/pcore/noeval.rb +1 -1
- data/lib/flor/pcore/noret.rb +1 -1
- data/lib/flor/pcore/push.rb +1 -1
- data/lib/flor/pcore/rand.rb +1 -1
- data/lib/flor/pcore/set.rb +1 -1
- data/lib/flor/pcore/twig.rb +2 -2
- data/lib/flor/pcore/until.rb +4 -1
- data/lib/flor/pcore/val.rb +1 -1
- data/lib/flor/punit/cancel.rb +2 -3
- data/lib/flor/punit/cmap.rb +5 -6
- data/lib/flor/punit/concurrence.rb +3 -5
- data/lib/flor/punit/schedule.rb +20 -5
- data/lib/flor/punit/signal.rb +1 -1
- data/lib/flor/punit/sleep.rb +2 -2
- data/lib/flor/punit/task.rb +3 -3
- data/lib/flor/punit/trace.rb +1 -1
- data/lib/flor/punit/trap.rb +22 -6
- data/lib/flor/to_string.rb +2 -1
- data/lib/flor/unit/executor.rb +3 -5
- data/lib/flor/unit/hooker.rb +2 -3
- data/lib/flor/unit/models/timer.rb +9 -3
- data/lib/flor/unit/models/trap.rb +1 -0
- data/lib/flor/unit/scheduler.rb +40 -35
- data/lib/flor/unit/storage.rb +70 -59
- data/lib/flor/unit/waiter.rb +2 -3
- data/t.txt +4 -0
- metadata +6 -4
- data/fail.txt +0 -3
- data/lib/flor/pcore/match.rb +0 -46
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
# flor CHANGELOG.md
|
3
3
|
|
4
4
|
|
5
|
+
## flor 0.12.0 released 2017-04-14
|
6
|
+
|
7
|
+
- Implementation of 'flank' and application to "trap" and "schedule"
|
8
|
+
- Introduce `{ a : 0 } quote: 'keys'`
|
9
|
+
- Introduce `vars: copy` or `vars: '*'`
|
10
|
+
|
11
|
+
|
5
12
|
## flor 0.11.0 released 2017-03-17
|
6
13
|
|
7
14
|
- Simplification of the tasker configuration files
|
data/Makefile
CHANGED
@@ -55,6 +55,9 @@ start:
|
|
55
55
|
backup_notes_and_todos:
|
56
56
|
tar czvf flor_notes_$(shell date "+%Y%m%d_%H%M").tgz .notes.md .todo.md && mv flor_notes_*.tgz ~/Dropbox/backup/
|
57
57
|
ba: backup_notes_and_todos
|
58
|
+
backup_src:
|
59
|
+
cd .. && tar czvf flor_$(shell date "+%Y%m%d_%H%M").tgz flor && mv flor_*.tgz ~/Dropbox/backup/
|
60
|
+
bak: backup_src
|
58
61
|
|
59
62
|
t:
|
60
63
|
tree spec/unit/loader
|
data/lib/flor.rb
CHANGED
data/lib/flor/colours.rb
CHANGED
@@ -69,12 +69,16 @@ module Flor
|
|
69
69
|
|
70
70
|
o = opts[:out] || $stdout
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
col =
|
73
|
+
(o.respond_to?(:log_colours?) ? o.log_colours? : o.tty?) ||
|
74
|
+
($0[-6..-1] == '/rspec' &&
|
75
|
+
(ARGV.include?('--tty') || ARGV.include?('--color')))
|
76
|
+
|
77
|
+
col ? @colours : @no_colours
|
75
78
|
end
|
76
79
|
|
77
80
|
def self.decolour(s)
|
81
|
+
|
78
82
|
s.gsub(/\x1b\[\d+(;\d+)?m/, '')
|
79
83
|
end
|
80
84
|
|
data/lib/flor/conf.rb
CHANGED
@@ -67,22 +67,24 @@ module Flor
|
|
67
67
|
#
|
68
68
|
# For example `debug: 'msg,stdout'`
|
69
69
|
|
70
|
-
def self.
|
70
|
+
def self.prepare(conf, over_conf)
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
h.merge!(interpret_flor_debug(h['flor_debug'] || h['debug']))
|
72
|
+
c = conf
|
73
|
+
c = Flor::ConfExecutor.interpret(c) if c.is_a?(String)
|
75
74
|
|
76
|
-
|
77
|
-
|
75
|
+
fail ArgumentError.new(
|
76
|
+
"cannot extract conf out of #{c.inspect} (#{conf.class})"
|
77
|
+
) unless c.is_a?(Hash)
|
78
78
|
|
79
|
-
|
79
|
+
unless c['conf'] == true
|
80
|
+
#
|
81
|
+
# don't read FLOR_DEBUG if this executor is only meant to read the conf
|
80
82
|
|
81
|
-
|
82
|
-
|
83
|
-
|
83
|
+
c.merge!(interpret_flor_debug(c))
|
84
|
+
c.merge!(interpret_env)
|
85
|
+
end
|
84
86
|
|
85
|
-
|
87
|
+
c.merge!(over_conf)
|
86
88
|
end
|
87
89
|
|
88
90
|
def self.get_class(conf, key)
|
@@ -99,11 +101,15 @@ module Flor
|
|
99
101
|
LOG_DBG_KEYS = %w[ dbg msg err src tree tree_rw run ]
|
100
102
|
LOG_ALL_KEYS = %w[ all log sto ] + LOG_DBG_KEYS
|
101
103
|
|
102
|
-
def self.interpret_flor_debug(
|
104
|
+
def self.interpret_flor_debug(c)
|
103
105
|
|
104
|
-
|
105
|
-
|
106
|
-
|
106
|
+
plus, minus = [ c['flor_debug'], c['debug'], ENV['FLOR_DEBUG'] ]
|
107
|
+
.collect { |v| (v || '').split(/\s*,\s*/) }
|
108
|
+
.flatten(1)
|
109
|
+
.partition { |v| v[0, 1] != '-' }
|
110
|
+
plus = plus.collect { |v| v[0, 1] == '+' ? v[1..-1] : v }
|
111
|
+
minus = minus.collect { |v| v[0, 1] == '-' ? v[1..-1] : v }
|
112
|
+
a = plus - minus
|
107
113
|
|
108
114
|
h =
|
109
115
|
a.inject({}) { |h, kv|
|
data/lib/flor/core/executor.rb
CHANGED
@@ -94,14 +94,16 @@ module Flor
|
|
94
94
|
(n['vars'] || {})
|
95
95
|
.each { |k, v| vs[k] = Flor.dup(v) unless vs.has_key?(k) }
|
96
96
|
|
97
|
-
|
97
|
+
pnid = n['parent']
|
98
|
+
|
99
|
+
if @unit.loader && pnid == nil && n['vdomain'] != false
|
98
100
|
|
99
101
|
@unit.loader.variables(n['vdomain'] || Flor.domain(@exid))
|
100
102
|
.each { |k, v| vs[k] = Flor.dup(v) unless vs.has_key?(k) }
|
101
103
|
end
|
102
104
|
|
103
105
|
if cn = n['cnid']; vars(cn, vs); end
|
104
|
-
|
106
|
+
vars(pnid, vs) if pnid
|
105
107
|
|
106
108
|
vs
|
107
109
|
end
|
@@ -132,7 +134,7 @@ module Flor
|
|
132
134
|
'ctime' => now,
|
133
135
|
'mtime' => now }
|
134
136
|
|
135
|
-
%w[ vars vdomain cnid
|
137
|
+
%w[ vars vdomain cnid dbg ].each do |k|
|
136
138
|
v = message[k]
|
137
139
|
node[k] = v if v != nil
|
138
140
|
end
|
@@ -140,7 +142,6 @@ module Flor
|
|
140
142
|
# vars: variables
|
141
143
|
# vdomain: variable domain (used in conjuction with the loader)
|
142
144
|
# cnid: closure nid
|
143
|
-
# noreply: this new node has a parent but shouldn't reply to it
|
144
145
|
# dbg: used to debug messages (useful @node['dbg'] when 'receive')
|
145
146
|
|
146
147
|
@execution['nodes'][nid] = node
|
@@ -179,7 +180,22 @@ module Flor
|
|
179
180
|
node['heat'] = heat = n.deref(t0)
|
180
181
|
node['heap'] = heap = n.reheap(tree, heat)
|
181
182
|
|
182
|
-
|
183
|
+
# "exceptions"
|
184
|
+
|
185
|
+
# TODO could those two ifs go upstream (top of this method)
|
186
|
+
# and thus become smaller
|
187
|
+
#
|
188
|
+
if message['accept_symbol'] && node['heat'] == nil
|
189
|
+
#
|
190
|
+
# tag: et al
|
191
|
+
|
192
|
+
tree = node['tree'] = message['tree'] = [ '_dqs', tree[0], tree[2] ]
|
193
|
+
|
194
|
+
node['heat0'] = tree[0]
|
195
|
+
node['heat'] = heat = n.deref(tree[0])
|
196
|
+
node['heap'] = heap = n.reheap(tree, heat)
|
197
|
+
|
198
|
+
elsif heap == 'task' && heat[0] == '_task'
|
183
199
|
#
|
184
200
|
# rewrite `alpha` into `task alpha`
|
185
201
|
|
@@ -208,13 +224,6 @@ module Flor
|
|
208
224
|
node['failure'] ? '_err' : nil
|
209
225
|
end
|
210
226
|
|
211
|
-
return ([{
|
212
|
-
'point' => 'receive',
|
213
|
-
'nid' => message['from'], 'from' => message['nid'],
|
214
|
-
'exid' => message['exid'],
|
215
|
-
'payload' => Flor.dupm(message['payload'], 'ret' => node['heat0'])
|
216
|
-
}]) if heap == nil && message['accept_symbol'] == true
|
217
|
-
|
218
227
|
return error_reply(
|
219
228
|
node, message, "don't know how to apply #{node['heat0'].inspect}"
|
220
229
|
) if heap == nil
|
@@ -224,99 +233,85 @@ module Flor
|
|
224
233
|
|
225
234
|
head = heac.new(self, node, message)
|
226
235
|
|
227
|
-
#return process(head.rewrite) if head.is_a?(Flor::Macro)
|
228
236
|
return [ head.rewrite ] if head.is_a?(Flor::Macro)
|
229
237
|
|
230
|
-
|
231
|
-
pt = message['point']
|
232
|
-
pt = "do_#{pt}" if pt == 'receive' || pt == 'cancel'
|
233
|
-
|
234
|
-
if pt == 'execute'
|
235
|
-
head.pre_execute
|
236
|
-
pnode = @execution['nodes'][node['parent']]
|
237
|
-
cnodes = pnode && (pnode['cnodes'] ||= [])
|
238
|
-
cnodes << nid if cnodes && ( ! cnodes.include?(nid))
|
239
|
-
end
|
240
|
-
head.send(pt)
|
238
|
+
head.send("do_#{message['point']}")
|
241
239
|
end
|
242
240
|
|
243
|
-
def
|
241
|
+
def toc_messages(message)
|
244
242
|
|
245
|
-
return
|
243
|
+
return [] if message['flavour'] == 'flank'
|
246
244
|
|
247
|
-
|
245
|
+
m = message.select { |k, v| %w[ exid nid from payload ].include?(k) }
|
246
|
+
m['sm'] = message['m']
|
247
|
+
m['point'] = message['from'] == '0' ? 'terminated' : 'ceased'
|
248
248
|
|
249
|
-
|
250
|
-
|
249
|
+
[ m ]
|
250
|
+
end
|
251
251
|
|
252
|
-
|
253
|
-
# don't remove the node if it's a closure for some other nodes
|
252
|
+
def receive(message)
|
254
253
|
|
255
|
-
|
254
|
+
messages = leave_node(message)
|
256
255
|
|
257
|
-
|
258
|
-
# don't remove if it's the "root" node
|
256
|
+
nid = message['nid']
|
259
257
|
|
260
|
-
|
261
|
-
|
258
|
+
return messages + toc_messages(message) unless nid
|
259
|
+
# 'terminated' or 'ceased'
|
262
260
|
|
263
|
-
|
261
|
+
node = @execution['nodes'][nid]
|
264
262
|
|
265
|
-
|
266
|
-
|
263
|
+
return messages unless node
|
264
|
+
# node gone...
|
267
265
|
|
268
|
-
|
269
|
-
{ 'point' => 'left',
|
270
|
-
'tags' => ts,
|
271
|
-
'exid' => exid,
|
272
|
-
'nid' => node['nid'],
|
273
|
-
'payload' => message['payload'] }
|
274
|
-
]
|
266
|
+
messages + apply(node, message)
|
275
267
|
end
|
276
268
|
|
277
|
-
|
278
|
-
#
|
279
|
-
def receive_toc(message, fnode)
|
269
|
+
def leave_node(message)
|
280
270
|
|
281
|
-
|
282
|
-
|
283
|
-
exid nid from payload
|
284
|
-
].inject({}) { |h, k| h[k] = message[k] if message.has_key?(k); h }
|
271
|
+
fnid = message['from']; return [] unless fnid
|
272
|
+
fnode = @execution['nodes'][fnid]; return [] unless fnode
|
285
273
|
|
286
|
-
|
274
|
+
return [] if message['flavour'] == 'flank'
|
287
275
|
|
288
|
-
|
289
|
-
|
290
|
-
'terminated'
|
291
|
-
else
|
292
|
-
'ceased'
|
293
|
-
end
|
294
|
-
|
295
|
-
[ msg ]
|
276
|
+
remove_node(message, fnode) +
|
277
|
+
leave_tags(message, fnode)
|
296
278
|
end
|
297
279
|
|
298
|
-
def
|
280
|
+
def remove_node(message, node)
|
299
281
|
|
300
|
-
|
301
|
-
|
282
|
+
nid = node['nid']
|
283
|
+
cls = node['closures']
|
302
284
|
|
303
|
-
|
304
|
-
|
305
|
-
end
|
285
|
+
pro = Flor::Procedure.make(self, node, message)
|
286
|
+
pro.end
|
306
287
|
|
307
|
-
|
308
|
-
messages = leave(fnode, message)
|
288
|
+
cancels = pro.send(:wrap_cancel_children, 'cancel_trailing' => true)
|
309
289
|
|
310
|
-
|
311
|
-
|
290
|
+
return cancels if cls && cls.any?
|
291
|
+
# don't remove the node if it's a closure for some other nodes
|
312
292
|
|
313
|
-
return
|
293
|
+
return cancels if nid == '0'
|
294
|
+
# don't remove if it's the "root" node
|
314
295
|
|
315
|
-
|
296
|
+
@unit.archive_node(message['exid'], node)
|
297
|
+
# archiving is only active during testing
|
316
298
|
|
317
|
-
|
299
|
+
@execution['nodes'].delete(nid)
|
318
300
|
|
319
|
-
|
301
|
+
cancels
|
302
|
+
end
|
303
|
+
|
304
|
+
def leave_tags(message, node)
|
305
|
+
|
306
|
+
ts = node['tags']; return [] unless ts && ts.any?
|
307
|
+
|
308
|
+
[
|
309
|
+
{ 'point' => 'left',
|
310
|
+
'tags' => ts,
|
311
|
+
'exid' => exid,
|
312
|
+
'nid' => node['nid'],
|
313
|
+
'payload' => message['payload'] }
|
314
|
+
]
|
320
315
|
end
|
321
316
|
|
322
317
|
def error_reply(node, message, err)
|
@@ -439,7 +434,6 @@ module Flor
|
|
439
434
|
[]
|
440
435
|
end
|
441
436
|
|
442
|
-
|
443
437
|
def failed(message)
|
444
438
|
|
445
439
|
n = node(message['nid'])
|
data/lib/flor/core/node.rb
CHANGED
@@ -73,6 +73,9 @@ class Flor::Node
|
|
73
73
|
def point; @message['point']; end
|
74
74
|
def from; @message['from']; end
|
75
75
|
|
76
|
+
def cnodes; @node['cnodes']; end
|
77
|
+
def cnodes_any?; cnodes && cnodes.any?; end
|
78
|
+
|
76
79
|
def payload
|
77
80
|
@message_payload ||= Payload.new(self, :message)
|
78
81
|
end
|
@@ -354,10 +357,12 @@ class Flor::Node
|
|
354
357
|
|
355
358
|
return vars[key] if vars && vars.has_key?(key)
|
356
359
|
|
357
|
-
if cnid = node['cnid']
|
360
|
+
if cnid = node['cnid']
|
358
361
|
cvars = (@execution['nodes'][cnid] || {})['vars']
|
359
362
|
return cvars[key] if cvars && cvars.has_key?(key)
|
360
363
|
end
|
364
|
+
#
|
365
|
+
# look into closure, just one level deep...
|
361
366
|
|
362
367
|
lookup_var(pnode, mod, key)
|
363
368
|
end
|
data/lib/flor/core/procedure.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
|
2
2
|
class Flor::Procedure < Flor::Node
|
3
3
|
|
4
|
-
|
4
|
+
class << self
|
5
5
|
|
6
|
-
(
|
7
|
-
end
|
6
|
+
def inherited(subclass)
|
8
7
|
|
9
|
-
|
8
|
+
(@@inherited ||= []) << subclass
|
9
|
+
end
|
10
10
|
|
11
|
-
|
12
|
-
end
|
11
|
+
def [](name)
|
13
12
|
|
14
|
-
|
13
|
+
@@inherited.find { |k| k.names && k.names.include?(name) }
|
14
|
+
end
|
15
15
|
|
16
16
|
def names(*names)
|
17
17
|
|
@@ -22,6 +22,24 @@ class Flor::Procedure < Flor::Node
|
|
22
22
|
end
|
23
23
|
|
24
24
|
alias :name :names
|
25
|
+
|
26
|
+
def make(executor, node, message)
|
27
|
+
|
28
|
+
heap = node['heat'] ? node['heap'] : nil
|
29
|
+
|
30
|
+
fail ArgumentError.new(
|
31
|
+
"cannot determine procedure " +
|
32
|
+
"#{{ heat: node['heat'], heap: node['heap'] }.inspect}"
|
33
|
+
) unless heap
|
34
|
+
|
35
|
+
heac = self[heap]
|
36
|
+
|
37
|
+
fail NameError.new(
|
38
|
+
"unknown procedure #{heap.inspect}"
|
39
|
+
) unless heac
|
40
|
+
|
41
|
+
heac.new(executor, node, message)
|
42
|
+
end
|
25
43
|
end
|
26
44
|
|
27
45
|
def pre_execute
|
@@ -38,13 +56,8 @@ class Flor::Procedure < Flor::Node
|
|
38
56
|
@node['on_receive_last'] =
|
39
57
|
apply(@node['on_error'].shift, [ @message ], tree[2])
|
40
58
|
|
41
|
-
|
42
|
-
|
43
|
-
if nids && nids.any?
|
44
|
-
cancel_children
|
45
|
-
else
|
46
|
-
do_receive # which should trigger 'on_receive_last'
|
47
|
-
end
|
59
|
+
do_wrap_cancel_children ||
|
60
|
+
do_receive # which should trigger 'on_receive_last'
|
48
61
|
end
|
49
62
|
|
50
63
|
def debug_tree(nid=nil)
|
@@ -60,6 +73,19 @@ class Flor::Procedure < Flor::Node
|
|
60
73
|
puts Flor.detail_msg(@executor, msg)
|
61
74
|
end
|
62
75
|
|
76
|
+
def end
|
77
|
+
|
78
|
+
end_node
|
79
|
+
end
|
80
|
+
|
81
|
+
def flank
|
82
|
+
|
83
|
+
@node['tree'] = Flor.dup(tree)
|
84
|
+
@node['noreply'] = true
|
85
|
+
|
86
|
+
wrap('nid' => parent, 'flavour' => 'flank')
|
87
|
+
end
|
88
|
+
|
63
89
|
protected
|
64
90
|
|
65
91
|
def counter_next(k)
|
@@ -162,7 +188,7 @@ class Flor::Procedure < Flor::Node
|
|
162
188
|
|
163
189
|
def execute_child(index=0, sub=nil, h=nil)
|
164
190
|
|
165
|
-
return
|
191
|
+
return wrap_reply \
|
166
192
|
if index < 0 || ( ! tree[1].is_a?(Array)) || tree[1][index] == nil
|
167
193
|
|
168
194
|
sub = counter_next('subs') if sub == true
|
@@ -176,7 +202,7 @@ class Flor::Procedure < Flor::Node
|
|
176
202
|
'payload' => payload.current }
|
177
203
|
hh.merge!(h) if h
|
178
204
|
|
179
|
-
|
205
|
+
wrap(hh)
|
180
206
|
end
|
181
207
|
|
182
208
|
def unatt_unkeyed_children(first_only=false)
|
@@ -221,6 +247,17 @@ class Flor::Procedure < Flor::Node
|
|
221
247
|
@node['tree'] = [ tree[0], cn, tree[2] ]
|
222
248
|
end
|
223
249
|
|
250
|
+
def do_execute
|
251
|
+
|
252
|
+
pre_execute
|
253
|
+
|
254
|
+
pnode = @execution['nodes'][parent]
|
255
|
+
cnodes = pnode && (pnode['cnodes'] ||= [])
|
256
|
+
cnodes << nid if cnodes && ( ! cnodes.include?(nid))
|
257
|
+
|
258
|
+
execute
|
259
|
+
end
|
260
|
+
|
224
261
|
def execute
|
225
262
|
|
226
263
|
receive
|
@@ -231,12 +268,10 @@ class Flor::Procedure < Flor::Node
|
|
231
268
|
#
|
232
269
|
def do_receive
|
233
270
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
nil
|
239
|
-
end
|
271
|
+
remove = @message['flavour'] != 'flank'
|
272
|
+
|
273
|
+
from_child = nil
|
274
|
+
from_child = cnodes.delete(from) if cnodes_any? && remove
|
240
275
|
|
241
276
|
if node_closed?
|
242
277
|
return receive_from_child_when_closed if from_child
|
@@ -273,7 +308,7 @@ class Flor::Procedure < Flor::Node
|
|
273
308
|
|
274
309
|
def receive_from_child_when_closed
|
275
310
|
|
276
|
-
(
|
311
|
+
(cnodes.empty? && pop_on_receive_last) || wrap_reply
|
277
312
|
end
|
278
313
|
|
279
314
|
def receive_when_closed
|
@@ -333,7 +368,7 @@ class Flor::Procedure < Flor::Node
|
|
333
368
|
|
334
369
|
def receive_last
|
335
370
|
|
336
|
-
|
371
|
+
wrap_reply
|
337
372
|
end
|
338
373
|
|
339
374
|
# Used by 'cursor' (and 'loop') when
|
@@ -356,21 +391,27 @@ class Flor::Procedure < Flor::Node
|
|
356
391
|
|
357
392
|
(@node['tags'] ||= []).concat(ret)
|
358
393
|
|
359
|
-
|
394
|
+
wrap('point' => 'entered', 'nid' => nid, 'tags' => ret)
|
360
395
|
end
|
361
396
|
|
362
|
-
def
|
397
|
+
def wrap(h={})
|
363
398
|
|
364
399
|
m = {}
|
365
400
|
m['point'] = 'receive'
|
366
401
|
m['exid'] = exid
|
367
|
-
m['nid'] = parent
|
402
|
+
m['nid'] = @node['noreply'] ? nil : parent
|
368
403
|
m['from'] = nid
|
369
404
|
|
370
405
|
m['sm'] = @message['m']
|
371
406
|
|
372
|
-
ret =
|
373
|
-
|
407
|
+
ret =
|
408
|
+
if @node.has_key?('aret') # from the 'ret' common attribute
|
409
|
+
@node['aret']
|
410
|
+
elsif h.has_key?('ret')
|
411
|
+
h.delete('ret')
|
412
|
+
else
|
413
|
+
:no
|
414
|
+
end
|
374
415
|
|
375
416
|
m['payload'] = payload.current
|
376
417
|
|
@@ -378,25 +419,32 @@ class Flor::Procedure < Flor::Node
|
|
378
419
|
|
379
420
|
m['payload']['ret'] = ret if ret != :no
|
380
421
|
|
381
|
-
end_node if m['nid'] == parent && m['point'] == 'receive'
|
382
|
-
|
383
422
|
[ m ]
|
384
423
|
end
|
385
424
|
|
386
|
-
|
425
|
+
alias wrap_reply wrap
|
426
|
+
|
427
|
+
def wrap_error(o)
|
428
|
+
|
429
|
+
wrap('point' => 'failed', 'error' => Flor.to_error(o))
|
430
|
+
end
|
431
|
+
|
432
|
+
def wrap_cancel(h)
|
387
433
|
|
388
|
-
|
434
|
+
h['point'] ||= 'cancel'
|
435
|
+
h['nid'] ||= nid
|
436
|
+
#h['flavour'] ||= 'xxx'
|
389
437
|
|
390
|
-
|
438
|
+
wrap(h)
|
391
439
|
end
|
392
440
|
|
393
|
-
def
|
441
|
+
def wrap_schedule(h)
|
394
442
|
|
395
443
|
h['point'] ||= 'schedule'
|
396
444
|
h['payload'] ||= {}
|
397
445
|
h['nid'] ||= nid
|
398
446
|
|
399
|
-
|
447
|
+
wrap(h)
|
400
448
|
end
|
401
449
|
|
402
450
|
def lookup_var_node(node, mode, k=nil)
|
@@ -483,7 +531,7 @@ class Flor::Procedure < Flor::Node
|
|
483
531
|
vars[key] = args[i]
|
484
532
|
end
|
485
533
|
|
486
|
-
ms =
|
534
|
+
ms = wrap(
|
487
535
|
'point' => 'execute',
|
488
536
|
'nid' => ani,
|
489
537
|
'tree' => [ '_apply', t[1], line ],
|
@@ -497,23 +545,28 @@ class Flor::Procedure < Flor::Node
|
|
497
545
|
ms
|
498
546
|
end
|
499
547
|
|
500
|
-
def
|
548
|
+
def wrap_cancel_nodes(nids, h)
|
501
549
|
|
502
550
|
(nids || [])
|
503
|
-
.collect { |i|
|
551
|
+
.collect { |i| wrap_cancel(h.merge('nid' => i, 'from' => nid)) }
|
504
552
|
.flatten(1)
|
505
553
|
end
|
506
554
|
|
507
|
-
def
|
555
|
+
def wrap_cancelled
|
508
556
|
|
509
|
-
|
557
|
+
wrap(
|
510
558
|
'cause' => 'cancel',
|
511
559
|
'payload' => @message['payload'] || @node['payload'])
|
512
560
|
end
|
513
561
|
|
514
|
-
def
|
562
|
+
def wrap_cancel_children(h={})
|
563
|
+
|
564
|
+
wrap_cancel_nodes(cnodes, h)
|
565
|
+
end
|
566
|
+
|
567
|
+
def do_wrap_cancel_children(h={})
|
515
568
|
|
516
|
-
|
569
|
+
wrap_cancel_children(h).instance_eval { |ms| ms.any? ? ms : nil }
|
517
570
|
end
|
518
571
|
|
519
572
|
# The executor calls #do_cancel, while most procedure implementations
|
@@ -521,15 +574,20 @@ class Flor::Procedure < Flor::Node
|
|
521
574
|
#
|
522
575
|
def do_cancel
|
523
576
|
|
524
|
-
|
577
|
+
if @message['flavour'] == 'kill'
|
578
|
+
|
579
|
+
return [] if node_ended?
|
580
|
+
kill
|
525
581
|
|
526
|
-
|
527
|
-
@node['on_receive_last'] = orl if orl
|
582
|
+
else
|
528
583
|
|
529
|
-
|
530
|
-
|
584
|
+
orl = @message['on_receive_last']
|
585
|
+
@node['on_receive_last'] = orl if orl
|
531
586
|
|
532
|
-
|
587
|
+
return cancel_when_ended if node_ended?
|
588
|
+
return cancel_when_closed if node_closed?
|
589
|
+
cancel
|
590
|
+
end
|
533
591
|
end
|
534
592
|
|
535
593
|
def cancel_when_ended
|
@@ -546,20 +604,16 @@ class Flor::Procedure < Flor::Node
|
|
546
604
|
|
547
605
|
close_node
|
548
606
|
|
549
|
-
|
550
|
-
|
551
|
-
if nids && nids.any?
|
552
|
-
cancel_children
|
553
|
-
else
|
554
|
-
cancel_reply
|
555
|
-
end
|
607
|
+
do_wrap_cancel_children ||
|
608
|
+
wrap_cancelled
|
556
609
|
end
|
557
610
|
|
558
611
|
def kill
|
559
612
|
|
560
|
-
|
613
|
+
close_node
|
561
614
|
|
562
|
-
|
615
|
+
wrap_cancel_children('flavour' => 'kill') +
|
616
|
+
wrap_cancelled
|
563
617
|
end
|
564
618
|
end
|
565
619
|
|