flor 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- 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),
|