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/pcore/cursor.rb
CHANGED
@@ -57,7 +57,7 @@ class Flor::Pro::Cursor < Flor::Procedure
|
|
57
57
|
@node['subs'] << counter_next('subs')
|
58
58
|
execute_child(first_non_att_child_id, @node['subs'].last)
|
59
59
|
else
|
60
|
-
|
60
|
+
wrap_reply
|
61
61
|
end
|
62
62
|
else
|
63
63
|
execute_child(@ncid, @node['subs'].last)
|
@@ -105,7 +105,7 @@ class Flor::Pro::Cursor < Flor::Procedure
|
|
105
105
|
if fla == 'continue'
|
106
106
|
|
107
107
|
@node['on_receive_last'] =
|
108
|
-
|
108
|
+
wrap(
|
109
109
|
'nid' => nid, 'from' => "#{nid}_#{children.size + 1}",
|
110
110
|
'orl' => fla,
|
111
111
|
'payload' => Flor.dup(message['payload']))
|
data/lib/flor/pcore/define.rb
CHANGED
data/lib/flor/pcore/fail.rb
CHANGED
@@ -20,12 +20,7 @@ class Flor::Pro::Fail < Flor::Procedure
|
|
20
20
|
(payload['ret'] || 'error').to_s,
|
21
21
|
Flor::Node.new(@executor, @node, @message))
|
22
22
|
|
23
|
-
|
24
|
-
#
|
25
|
-
# let's reply with the failed message directly,
|
26
|
-
# no need for a Ruby backtrace, it's an error at the Flor level.
|
27
|
-
#
|
28
|
-
reply('point' => 'failed', 'error' => Flor.to_error(err))
|
23
|
+
wrap_error(err)
|
29
24
|
end
|
30
25
|
end
|
31
26
|
|
data/lib/flor/pcore/if.rb
CHANGED
@@ -52,7 +52,7 @@ class Flor::Pro::If < Flor::Procedure
|
|
52
52
|
|
53
53
|
def receive_non_att
|
54
54
|
|
55
|
-
return
|
55
|
+
return wrap_reply if @fcid > first_unkeyed_child_id
|
56
56
|
# "else" or "then" answered, replying to parent...
|
57
57
|
|
58
58
|
off =
|
@@ -65,7 +65,7 @@ class Flor::Pro::If < Flor::Procedure
|
|
65
65
|
nxt = @fcid + off
|
66
66
|
|
67
67
|
if nxt >= children.size
|
68
|
-
|
68
|
+
wrap_reply('ret' => node_payload_ret)
|
69
69
|
else
|
70
70
|
execute_child(nxt)
|
71
71
|
end
|
data/lib/flor/pcore/map.rb
CHANGED
@@ -40,7 +40,7 @@ class Flor::Pro::Map < Flor::Procedure
|
|
40
40
|
@node['idx'] += 1
|
41
41
|
@node['mtime'] = Flor.tstamp
|
42
42
|
|
43
|
-
return
|
43
|
+
return wrap_reply('ret' => @node['res']) \
|
44
44
|
if @node['idx'] == @node['col'].size
|
45
45
|
|
46
46
|
@node['vars']['idx'] = @node['idx']
|
@@ -0,0 +1,92 @@
|
|
1
|
+
|
2
|
+
class Flor::Pro::Matchr < Flor::Procedure
|
3
|
+
#
|
4
|
+
# Matches a string against a regular expression.
|
5
|
+
#
|
6
|
+
# `matchr s r` will return an array of matching strings in `s` from regular
|
7
|
+
# expression `r`.
|
8
|
+
#
|
9
|
+
# `match? s r` will return true if string `s` matches regular expression `r`.
|
10
|
+
# It returns false else.
|
11
|
+
#
|
12
|
+
# ```
|
13
|
+
# matchr "alpha", /bravo/
|
14
|
+
# # yields an empty array []
|
15
|
+
#
|
16
|
+
# match? "alpha", /bravo/ # => false
|
17
|
+
# match? "alpha", /alp/ # => true
|
18
|
+
# ```
|
19
|
+
#
|
20
|
+
# The second argument to `match?` and `matchr` is turned into a
|
21
|
+
# regular expression.
|
22
|
+
# ```
|
23
|
+
# match? "alpha", 'alp' # => true
|
24
|
+
# ```
|
25
|
+
#
|
26
|
+
# When there is a single argument, `matchr` and `match?` will try
|
27
|
+
# to take the string out of `$(f.ret)`.
|
28
|
+
# ```
|
29
|
+
# "blue moon"
|
30
|
+
# match? (/blue/)
|
31
|
+
# # => true
|
32
|
+
#
|
33
|
+
# "blue moon"
|
34
|
+
# match? 'blue'
|
35
|
+
# # => true
|
36
|
+
#
|
37
|
+
# /blue/
|
38
|
+
# match? 'blue moon'
|
39
|
+
# # => true
|
40
|
+
#
|
41
|
+
# 'blue'
|
42
|
+
# match? (/black/)
|
43
|
+
# # => false
|
44
|
+
# ```
|
45
|
+
|
46
|
+
names %w[ matchr match? ]
|
47
|
+
|
48
|
+
def pre_execute
|
49
|
+
|
50
|
+
@node['rets'] = []
|
51
|
+
end
|
52
|
+
|
53
|
+
def receive_last
|
54
|
+
|
55
|
+
rex, str = arguments
|
56
|
+
|
57
|
+
m = rex.match(str)
|
58
|
+
|
59
|
+
payload['ret'] =
|
60
|
+
if @node['heap'] == 'match?'
|
61
|
+
!! m
|
62
|
+
else
|
63
|
+
m ? m.to_a : []
|
64
|
+
end
|
65
|
+
|
66
|
+
wrap_reply
|
67
|
+
end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
def arguments
|
72
|
+
|
73
|
+
rets = @node['rets'].dup
|
74
|
+
rets.unshift(node_payload_ret) if rets.size < 2
|
75
|
+
|
76
|
+
fail ArgumentError.new(
|
77
|
+
"'#{tree[0]}' needs 1 or 2 arguments"
|
78
|
+
) if rets.size < 2
|
79
|
+
|
80
|
+
rex =
|
81
|
+
rets.find { |r| r.is_a?(Array) && r[0] == '_rxs' } ||
|
82
|
+
rets.last
|
83
|
+
|
84
|
+
str = (rets - [ rex ]).first
|
85
|
+
|
86
|
+
rex = rex.is_a?(String) ? rex : rex[1].to_s
|
87
|
+
rex = rex.match(/\A\/[^\/]*\/[a-z]*\z/) ? Kernel.eval(rex) : Regexp.new(rex)
|
88
|
+
|
89
|
+
[ rex, str ]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
data/lib/flor/pcore/move.rb
CHANGED
@@ -27,10 +27,9 @@ class Flor::Pro::Move < Flor::Procedure
|
|
27
27
|
|
28
28
|
to = att('to')
|
29
29
|
|
30
|
-
rep = is_ancestor_node?(nid) ? [] :
|
30
|
+
rep = is_ancestor_node?(nid) ? [] : wrap_reply
|
31
31
|
|
32
|
-
|
33
|
-
'point' => 'cancel',
|
32
|
+
wrap_cancel(
|
34
33
|
'nid' => nid,
|
35
34
|
'flavour' => @node['heap'], # "move"
|
36
35
|
'payload' => rep.any? ? payload.copy_current : payload.current,
|
data/lib/flor/pcore/noeval.rb
CHANGED
data/lib/flor/pcore/noret.rb
CHANGED
data/lib/flor/pcore/push.rb
CHANGED
data/lib/flor/pcore/rand.rb
CHANGED
data/lib/flor/pcore/set.rb
CHANGED
data/lib/flor/pcore/twig.rb
CHANGED
@@ -14,7 +14,7 @@ class Flor::Pro::Twig < Flor::Procedure
|
|
14
14
|
nac = non_att_children
|
15
15
|
|
16
16
|
if nac.size == 1
|
17
|
-
|
17
|
+
wrap_reply('ret' => nac.first)
|
18
18
|
else
|
19
19
|
super
|
20
20
|
end
|
@@ -26,7 +26,7 @@ class Flor::Pro::Twig < Flor::Procedure
|
|
26
26
|
|
27
27
|
set_value(payload['ret'], t)
|
28
28
|
|
29
|
-
|
29
|
+
wrap
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
data/lib/flor/pcore/until.rb
CHANGED
@@ -36,13 +36,15 @@ class Flor::Pro::Until < Flor::Procedure
|
|
36
36
|
# over
|
37
37
|
|
38
38
|
ret = @node.has_key?('cret') ? @node['cret'] : node_payload_ret
|
39
|
-
|
39
|
+
|
40
|
+
wrap_reply('ret' => ret)
|
40
41
|
|
41
42
|
else
|
42
43
|
#
|
43
44
|
# condition yield false, enter "block"
|
44
45
|
|
45
46
|
payload['ret'] = node_payload_ret
|
47
|
+
|
46
48
|
execute_child(@ncid, @node['subs'].last)
|
47
49
|
end
|
48
50
|
|
@@ -54,6 +56,7 @@ class Flor::Pro::Until < Flor::Procedure
|
|
54
56
|
|
55
57
|
@node['cret'] = payload['ret']
|
56
58
|
payload['ret'] = node_payload_ret
|
59
|
+
|
57
60
|
execute_child(first_unkeyed_child_id, @node['subs'].last)
|
58
61
|
|
59
62
|
else
|
data/lib/flor/pcore/val.rb
CHANGED
data/lib/flor/punit/cancel.rb
CHANGED
@@ -37,9 +37,8 @@ class Flor::Pro::Cancel < Flor::Procedure
|
|
37
37
|
|
38
38
|
fla = @node['heap']
|
39
39
|
|
40
|
-
nids.uniq.
|
41
|
-
|
42
|
-
} + reply
|
40
|
+
nids.uniq.map { |nid| wrap_cancel('nid' => nid, 'flavour' => fla)[0] } +
|
41
|
+
wrap_reply
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
data/lib/flor/punit/cmap.rb
CHANGED
@@ -30,23 +30,22 @@ class Flor::Pro::Cmap < Flor::Procedure
|
|
30
30
|
"cmap expects a function"
|
31
31
|
) unless Flor.is_func_tree?(fun)
|
32
32
|
|
33
|
-
col = att(nil)
|
34
33
|
@node['fun'] = fun
|
35
34
|
|
36
|
-
|
37
|
-
apply(
|
38
|
-
|
35
|
+
att(nil)
|
36
|
+
.collect.with_index { |e, i| apply(fun, [ e, i ], tree[2]) }
|
37
|
+
.flatten(1)
|
39
38
|
end
|
40
39
|
|
41
40
|
def receive_elt
|
42
41
|
|
43
42
|
@node['col'] << payload['ret']
|
44
43
|
|
45
|
-
return [] if
|
44
|
+
return [] if cnodes_any?
|
46
45
|
|
47
46
|
payload['ret'] = @node['col']
|
48
47
|
|
49
|
-
|
48
|
+
wrap
|
50
49
|
end
|
51
50
|
end
|
52
51
|
|
@@ -64,7 +64,7 @@ class Flor::Pro::Concurrence < Flor::Procedure
|
|
64
64
|
|
65
65
|
def receive_last_att
|
66
66
|
|
67
|
-
return
|
67
|
+
return wrap_reply unless children[@ncid]
|
68
68
|
|
69
69
|
(@ncid..children.size - 1)
|
70
70
|
.map { |i| execute_child(i, 0, 'payload' => payload.copy_current) }
|
@@ -78,8 +78,6 @@ class Flor::Pro::Concurrence < Flor::Procedure
|
|
78
78
|
@node['receiver'] ||= determine_receiver
|
79
79
|
@node['merger'] ||= determine_merger
|
80
80
|
|
81
|
-
(@node['cnodes'] || []).delete(from)
|
82
|
-
|
83
81
|
return [] if @node['over']
|
84
82
|
|
85
83
|
over = invoke_receiver
|
@@ -93,7 +91,7 @@ class Flor::Pro::Concurrence < Flor::Procedure
|
|
93
91
|
# determine post-concurrence payload
|
94
92
|
|
95
93
|
cancel_remaining +
|
96
|
-
|
94
|
+
wrap_reply('payload' => pld)
|
97
95
|
end
|
98
96
|
|
99
97
|
def receive_from_child_when_closed
|
@@ -132,7 +130,7 @@ class Flor::Pro::Concurrence < Flor::Procedure
|
|
132
130
|
|
133
131
|
return [] if rem == 'forget'
|
134
132
|
|
135
|
-
|
133
|
+
wrap_cancel_children
|
136
134
|
end
|
137
135
|
|
138
136
|
def invoke_receiver
|
data/lib/flor/punit/schedule.rb
CHANGED
@@ -26,19 +26,34 @@ class Flor::Pro::Schedule < Flor::Procedure
|
|
26
26
|
"missing a function to call when the scheduler triggers"
|
27
27
|
) unless fun
|
28
28
|
|
29
|
-
|
29
|
+
m = apply(fun, [], tree[2], false).first
|
30
30
|
|
31
|
-
|
31
|
+
t, s =
|
32
32
|
@node['atts'].find { |k, v| %w[ cron at in every ].include?(k) } ||
|
33
33
|
@node['atts'].find { |k, v| k == nil }
|
34
34
|
|
35
35
|
fail ArgumentError.new(
|
36
36
|
"missing a schedule"
|
37
|
-
) unless
|
37
|
+
) unless s
|
38
38
|
|
39
|
-
|
39
|
+
@node['scheduled'] = true
|
40
40
|
|
41
|
-
|
41
|
+
wrap_schedule('type' => t, 'string' => s, 'message' => m) +
|
42
|
+
flank
|
43
|
+
end
|
44
|
+
|
45
|
+
def receive
|
46
|
+
|
47
|
+
return [] if @node['scheduled']
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
51
|
+
# "schedule" keeps track of its children, but does not cascade 'cancel'
|
52
|
+
# to them, unless the cancel flavour is 'kill'.
|
53
|
+
#
|
54
|
+
def wrap_cancel_children(h={})
|
55
|
+
|
56
|
+
h['flavour'] == 'kill' ? super : []
|
42
57
|
end
|
43
58
|
end
|
44
59
|
|
data/lib/flor/punit/signal.rb
CHANGED
data/lib/flor/punit/sleep.rb
CHANGED
@@ -21,9 +21,9 @@ class Flor::Pro::Sleep < Flor::Procedure
|
|
21
21
|
t = att('for', nil)
|
22
22
|
fail ArgumentError.new("missing a sleep time duration") unless t
|
23
23
|
|
24
|
-
m =
|
24
|
+
m = wrap('point' => 'receive').first
|
25
25
|
|
26
|
-
|
26
|
+
wrap_schedule('type' => 'in', 'string' => t, 'message' => m)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
data/lib/flor/punit/task.rb
CHANGED
@@ -10,7 +10,7 @@ class Flor::Pro::Task < Flor::Procedure
|
|
10
10
|
|
11
11
|
def do_receive
|
12
12
|
|
13
|
-
return
|
13
|
+
return wrap_reply('payload' => determine_reply_payload) \
|
14
14
|
if point == 'receive' && from == nil
|
15
15
|
|
16
16
|
super
|
@@ -38,7 +38,7 @@ class Flor::Pro::Task < Flor::Procedure
|
|
38
38
|
|
39
39
|
attl, attd = determine_atts
|
40
40
|
|
41
|
-
|
41
|
+
wrap(
|
42
42
|
'point' => 'task',
|
43
43
|
'exid' => exid, 'nid' => nid,
|
44
44
|
'tasker' => tasker,
|
@@ -52,7 +52,7 @@ class Flor::Pro::Task < Flor::Procedure
|
|
52
52
|
|
53
53
|
attl, attd = determine_atts
|
54
54
|
|
55
|
-
|
55
|
+
wrap(
|
56
56
|
'point' => 'detask',
|
57
57
|
'exid' => exid, 'nid' => nid,
|
58
58
|
'tasker' => att(nil),
|