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/lib/flor/punit/trace.rb
CHANGED
data/lib/flor/punit/trap.rb
CHANGED
@@ -42,13 +42,14 @@ class Flor::Pro::Trap < Flor::Procedure
|
|
42
42
|
|
43
43
|
msg =
|
44
44
|
if fun
|
45
|
-
apply(fun, [], tree[2], false).first
|
45
|
+
apply(fun, [], tree[2], false).first
|
46
46
|
else
|
47
|
-
|
47
|
+
wrap_reply.first
|
48
48
|
end
|
49
49
|
|
50
50
|
tra = {}
|
51
|
-
tra['
|
51
|
+
tra['nid'] = nid
|
52
|
+
tra['bnid'] = parent || '0'
|
52
53
|
tra['points'] = points
|
53
54
|
tra['tags'] = tags
|
54
55
|
tra['heaps'] = heaps
|
@@ -63,14 +64,29 @@ class Flor::Pro::Trap < Flor::Procedure
|
|
63
64
|
|
64
65
|
tra['range'] = att('range') || att('scope') || 'subnid'
|
65
66
|
|
66
|
-
|
67
|
-
|
67
|
+
@node['trapped'] = true
|
68
|
+
|
69
|
+
wrap('point' => 'trap', 'nid' => nid, 'trap' => tra) +
|
70
|
+
(fun ? flank : [])
|
68
71
|
end
|
69
72
|
|
70
73
|
def receive_last
|
71
74
|
|
72
|
-
#fail ArgumentError.new('trap requires a function')
|
73
75
|
receive_non_att
|
74
76
|
end
|
77
|
+
|
78
|
+
def receive
|
79
|
+
|
80
|
+
return [] if @node['trapped']
|
81
|
+
super
|
82
|
+
end
|
83
|
+
|
84
|
+
# "trap" keeps track of its children, but does not cascade 'cancel' to them,
|
85
|
+
# unless the cancel flavour is 'kill'.
|
86
|
+
#
|
87
|
+
def wrap_cancel_children(h={})
|
88
|
+
|
89
|
+
h['flavour'] == 'kill' ? super : []
|
90
|
+
end
|
75
91
|
end
|
76
92
|
|
data/lib/flor/to_string.rb
CHANGED
data/lib/flor/unit/executor.rb
CHANGED
@@ -70,8 +70,6 @@ module Flor
|
|
70
70
|
m = @messages.shift
|
71
71
|
end
|
72
72
|
|
73
|
-
point = m['point']
|
74
|
-
|
75
73
|
ms = process(m)
|
76
74
|
|
77
75
|
@consumed << m
|
@@ -86,11 +84,11 @@ module Flor
|
|
86
84
|
@unit.storage.put_messages(oms)
|
87
85
|
end
|
88
86
|
|
89
|
-
@unit.storage.consume(@consumed)
|
90
|
-
|
91
87
|
@alive = false
|
92
88
|
|
93
89
|
@unit.storage.put_execution(@execution)
|
90
|
+
@unit.storage.consume(@consumed)
|
91
|
+
|
94
92
|
@unit.storage.put_messages(@messages)
|
95
93
|
|
96
94
|
du = Time.now - t0
|
@@ -135,7 +133,7 @@ module Flor
|
|
135
133
|
|
136
134
|
def schedule(message)
|
137
135
|
|
138
|
-
@unit.
|
136
|
+
@unit.schedule(message)
|
139
137
|
|
140
138
|
[]
|
141
139
|
end
|
data/lib/flor/unit/hooker.rb
CHANGED
@@ -134,10 +134,10 @@ module Flor
|
|
134
134
|
|
135
135
|
if hook.is_a?(Flor::Trap) && o(opts, :subnid)
|
136
136
|
if node = executor.node(message['nid'], true)
|
137
|
-
return false unless node.descendant_of?(hook.
|
137
|
+
return false unless node.descendant_of?(hook.bnid, true)
|
138
138
|
node = node.h
|
139
139
|
else
|
140
|
-
return false if hook.
|
140
|
+
return false if hook.bnid != '0'
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
@@ -145,7 +145,6 @@ module Flor
|
|
145
145
|
return false unless node ||= executor.node(message['nid'])
|
146
146
|
return false unless hps.include?(node['heap'])
|
147
147
|
end
|
148
|
-
#p :yyy if hook.is_a?(Flor::Trap)
|
149
148
|
|
150
149
|
if hts = o(opts, :heat, :ht, [])
|
151
150
|
return false unless node ||= executor.node(message['nid'])
|
@@ -5,17 +5,23 @@ module Flor
|
|
5
5
|
|
6
6
|
def to_trigger_message
|
7
7
|
|
8
|
-
|
8
|
+
d = self.data(false)
|
9
|
+
|
10
|
+
m = d['message']
|
9
11
|
m['timer_id'] = self.id
|
10
12
|
|
13
|
+
sm = d['m']
|
14
|
+
|
11
15
|
{
|
12
16
|
'point' => 'trigger',
|
13
17
|
'exid' => self.exid,
|
14
|
-
'nid' => self.
|
18
|
+
'nid' => self.onid,
|
19
|
+
'bnid' => self.nid,
|
15
20
|
'type' => self.type,
|
16
21
|
'schedule' => self.schedule,
|
17
22
|
'timer_id' => self.id,
|
18
|
-
'message' => m
|
23
|
+
'message' => m,
|
24
|
+
'sm' => sm
|
19
25
|
}
|
20
26
|
end
|
21
27
|
|
data/lib/flor/unit/scheduler.rb
CHANGED
@@ -14,9 +14,7 @@ module Flor
|
|
14
14
|
|
15
15
|
def initialize(conf={}, over_conf={})
|
16
16
|
|
17
|
-
@conf =
|
18
|
-
@conf.merge!(Flor::Conf.read_env)
|
19
|
-
@conf.merge!(over_conf)
|
17
|
+
@conf = Flor::Conf.prepare(conf, over_conf)
|
20
18
|
|
21
19
|
fail ArgumentError.new(
|
22
20
|
"invalid domain name #{@conf['domain']}"
|
@@ -65,7 +63,7 @@ module Flor
|
|
65
63
|
#
|
66
64
|
Kernel.const_set(c, self) if c
|
67
65
|
|
68
|
-
@archive = nil # used, so far, only for testing
|
66
|
+
@archive = @conf['archive'] ? {} : nil # used, so far, only for testing
|
69
67
|
end
|
70
68
|
|
71
69
|
def name
|
@@ -254,27 +252,26 @@ module Flor
|
|
254
252
|
nil
|
255
253
|
end
|
256
254
|
|
257
|
-
def cancel(
|
255
|
+
def cancel(exid, *as)
|
258
256
|
|
259
|
-
queue(prepare_message('cancel',
|
257
|
+
queue(*prepare_message('cancel', [ exid, *as ]))
|
260
258
|
end
|
261
259
|
|
262
260
|
def signal(name, h={})
|
263
261
|
|
264
262
|
h[:payload] ||= {}
|
265
263
|
h[:name] ||= name
|
266
|
-
|
264
|
+
|
265
|
+
queue(*prepare_message('signal', [ h ]))
|
267
266
|
end
|
268
267
|
|
269
|
-
def re_apply(
|
268
|
+
def re_apply(exid, *as)
|
270
269
|
|
271
|
-
queue(prepare_message('cancel',
|
270
|
+
queue(*prepare_message('cancel', [ exid, *as, { re_apply: true } ]))
|
272
271
|
end
|
273
272
|
|
274
|
-
def
|
273
|
+
def schedule(message)
|
275
274
|
|
276
|
-
#timer = @storage.put_timer(message)
|
277
|
-
#@mutex.synchronize { @timers.push(timer).sort_by!(&:ntime) }
|
278
275
|
@storage.put_timer(message)
|
279
276
|
end
|
280
277
|
|
@@ -304,16 +301,14 @@ module Flor
|
|
304
301
|
@storage.put_trap(node, tra)
|
305
302
|
end
|
306
303
|
|
307
|
-
def
|
304
|
+
def archive_node(exid, node)
|
308
305
|
|
309
|
-
|
310
|
-
|
306
|
+
(@archive[exid] ||= {})[node['nid']] = Flor.dup(node) if @archive
|
307
|
+
end
|
311
308
|
|
312
|
-
|
313
|
-
# @timers.reject! { |t| t.exid == exid && t.nid == n['nid'] }
|
314
|
-
#end
|
309
|
+
def archived_node(exid, nid)
|
315
310
|
|
316
|
-
(@archive[exid]
|
311
|
+
(@archive[exid] || {})[nid]
|
317
312
|
end
|
318
313
|
|
319
314
|
def executor(exid)
|
@@ -362,35 +357,45 @@ module Flor
|
|
362
357
|
puts on_start_exc(ex)
|
363
358
|
end
|
364
359
|
|
365
|
-
def prepare_on_receive_last(
|
360
|
+
def prepare_on_receive_last(msg, opts)
|
366
361
|
|
367
|
-
|
368
|
-
|
369
|
-
t = h[:tree] || h['tree']
|
370
|
-
pl = h[:payload] || h['payload']
|
362
|
+
fail ArgumentError.new("missing 'payload' to re_apply") \
|
363
|
+
unless msg['payload']
|
371
364
|
|
372
|
-
|
373
|
-
|
374
|
-
t = Flor::Lang.parse(t, 're_apply', {})
|
365
|
+
t = Flor::Lang.parse(opts[:tree], 're_apply', {})
|
375
366
|
|
376
367
|
[
|
377
368
|
{ 'point' => 'execute',
|
378
|
-
'exid' =>
|
369
|
+
'exid' => msg['exid'], 'nid' => msg['nid'],
|
379
370
|
'from' => 'parent',
|
380
371
|
'tree' => t,
|
381
|
-
'payload' =>
|
372
|
+
'payload' => msg['payload'] }
|
382
373
|
]
|
383
374
|
end
|
384
375
|
|
385
|
-
def prepare_message(point,
|
376
|
+
def prepare_message(point, args)
|
377
|
+
|
378
|
+
h =
|
379
|
+
args.inject({}) { |hh, a|
|
380
|
+
if a.is_a?(Hash) then a.each { |k, v| hh[k.to_s] = v }
|
381
|
+
elsif ! hh.has_key?('exid') then hh['exid'] = a
|
382
|
+
elsif ! hh.has_key?('nid') then hh['nid'] = a
|
383
|
+
end
|
384
|
+
hh }
|
386
385
|
|
387
386
|
msg = { 'point' => point }
|
387
|
+
opts = {}
|
388
388
|
|
389
|
-
|
390
|
-
|
389
|
+
h.each do |k, v|
|
390
|
+
if %w[ exid name nid payload on_receive_last ].include?(k)
|
391
|
+
msg[k] = v
|
392
|
+
else
|
393
|
+
opts[k.to_sym] = v
|
394
|
+
end
|
395
|
+
end
|
391
396
|
|
392
|
-
if
|
393
|
-
msg['on_receive_last'] = prepare_on_receive_last(
|
397
|
+
if opts[:re_apply]
|
398
|
+
msg['on_receive_last'] = prepare_on_receive_last(msg, opts)
|
394
399
|
end
|
395
400
|
|
396
401
|
fail ArgumentError.new('missing :exid key') \
|
@@ -398,7 +403,7 @@ module Flor
|
|
398
403
|
fail ArgumentError.new('missing :name string key') \
|
399
404
|
if point == 'signal' && ! msg['name'].is_a?(String)
|
400
405
|
|
401
|
-
msg
|
406
|
+
[ msg, opts ]
|
402
407
|
end
|
403
408
|
|
404
409
|
def make_idle_message
|
data/lib/flor/unit/storage.rb
CHANGED
@@ -121,27 +121,25 @@ module Flor
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
-
def put_execution(
|
124
|
+
def put_execution(exe)
|
125
125
|
|
126
126
|
status =
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
'active'
|
131
|
-
end
|
127
|
+
exe['nodes'].find { |_, n| n['status'].last['status'] != 'ended' } ?
|
128
|
+
'active' :
|
129
|
+
'terminated'
|
132
130
|
|
133
|
-
id =
|
131
|
+
id = exe['id']
|
134
132
|
|
135
133
|
if id
|
136
134
|
|
137
|
-
|
135
|
+
exe['end'] ||= Flor.tstamp \
|
138
136
|
if status == 'terminated'
|
139
|
-
|
140
|
-
if
|
137
|
+
exe['duration'] = Time.parse(exe['end']) - Time.parse(exe['start']) \
|
138
|
+
if exe['end']
|
141
139
|
end
|
142
140
|
|
143
|
-
data = to_blob(
|
144
|
-
|
141
|
+
data = to_blob(exe)
|
142
|
+
exe['size'] = data.length
|
145
143
|
u = @unit.identifier
|
146
144
|
|
147
145
|
transync do
|
@@ -160,13 +158,13 @@ module Flor
|
|
160
158
|
|
161
159
|
else
|
162
160
|
|
163
|
-
|
161
|
+
exe['id'] =
|
164
162
|
@db[:flor_executions]
|
165
163
|
.insert(
|
166
|
-
domain: Flor.domain(
|
167
|
-
exid:
|
164
|
+
domain: Flor.domain(exe['exid']),
|
165
|
+
exid: exe['exid'],
|
168
166
|
content: data,
|
169
|
-
status:
|
167
|
+
status: status,
|
170
168
|
ctime: now,
|
171
169
|
mtime: now,
|
172
170
|
cunit: u,
|
@@ -174,15 +172,15 @@ module Flor
|
|
174
172
|
.to_i
|
175
173
|
end
|
176
174
|
|
177
|
-
remove_nodes(
|
178
|
-
update_pointers(
|
175
|
+
remove_nodes(exe, status, now)
|
176
|
+
update_pointers(exe, status, now)
|
179
177
|
end
|
180
178
|
|
181
|
-
|
179
|
+
exe
|
182
180
|
|
183
181
|
rescue => err
|
184
182
|
|
185
|
-
Thread.current[:sto_errored_items] = [
|
183
|
+
Thread.current[:sto_errored_items] = [ exe ]
|
186
184
|
raise err
|
187
185
|
end
|
188
186
|
|
@@ -351,6 +349,13 @@ module Flor
|
|
351
349
|
.where { mtime < tstamp }
|
352
350
|
.update(status: 'created')
|
353
351
|
end
|
352
|
+
|
353
|
+
rescue => err
|
354
|
+
|
355
|
+
@unit.logger.warn(
|
356
|
+
"#{self.class}#unreserve_messages(#{max_sec})", err, '(returning nil)')
|
357
|
+
|
358
|
+
-1 # not zero, to indicate a problem
|
354
359
|
end
|
355
360
|
|
356
361
|
def put_timer(message)
|
@@ -364,20 +369,23 @@ module Flor
|
|
364
369
|
|
365
370
|
synchronize do
|
366
371
|
|
367
|
-
@db[:flor_timers]
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
372
|
+
@db[:flor_timers]
|
373
|
+
.insert(
|
374
|
+
domain: Flor.domain(message['exid']),
|
375
|
+
exid: message['exid'],
|
376
|
+
nid: message['nid'],
|
377
|
+
onid: message['onid'] || message['nid'],
|
378
|
+
bnid: message['nid'],
|
379
|
+
type: type,
|
380
|
+
schedule: string,
|
381
|
+
ntime: next_time,
|
382
|
+
content: to_blob(message),
|
383
|
+
count: 0,
|
384
|
+
status: 'active',
|
385
|
+
ctime: now,
|
386
|
+
mtime: now,
|
387
|
+
cunit: u,
|
388
|
+
munit: u)
|
381
389
|
end
|
382
390
|
|
383
391
|
@unit.wake_up
|
@@ -414,22 +422,24 @@ module Flor
|
|
414
422
|
id =
|
415
423
|
synchronize do
|
416
424
|
|
417
|
-
@db[:flor_traps]
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
425
|
+
@db[:flor_traps]
|
426
|
+
.insert(
|
427
|
+
domain: dom,
|
428
|
+
exid: exid,
|
429
|
+
nid: tra['nid'],
|
430
|
+
onid: tra['onid'] || tra['nid'],
|
431
|
+
bnid: tra['bnid'],
|
432
|
+
trange: tra['range'],
|
433
|
+
tpoints: tra['points'],
|
434
|
+
ttags: tra['tags'],
|
435
|
+
theats: tra['heats'],
|
436
|
+
theaps: tra['heaps'],
|
437
|
+
content: to_blob(tra),
|
438
|
+
status: 'active',
|
439
|
+
ctime: now,
|
440
|
+
mtime: now,
|
441
|
+
cunit: u,
|
442
|
+
munit: u)
|
433
443
|
end
|
434
444
|
|
435
445
|
traps[id]
|
@@ -446,14 +456,15 @@ module Flor
|
|
446
456
|
|
447
457
|
synchronize do
|
448
458
|
|
449
|
-
@db[:flor_traces]
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
459
|
+
@db[:flor_traces]
|
460
|
+
.insert(
|
461
|
+
domain: Flor.domain(exid),
|
462
|
+
exid: exid,
|
463
|
+
nid: nid,
|
464
|
+
tracer: tracer,
|
465
|
+
text: text,
|
466
|
+
ctime: Flor.tstamp,
|
467
|
+
cunit: @unit.identifier)
|
457
468
|
end
|
458
469
|
end
|
459
470
|
|
@@ -558,7 +569,7 @@ module Flor
|
|
558
569
|
|
559
570
|
exid = exe['exid']
|
560
571
|
|
561
|
-
x = status == 'terminated' ? {} : { nid: exe['nodes'].keys }
|
572
|
+
x = (status == 'terminated') ? {} : { nid: exe['nodes'].keys }
|
562
573
|
# if 'terminated' include all nodes
|
563
574
|
|
564
575
|
if @archive
|