oflow 0.6.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +23 -41
- data/lib/oflow.rb +2 -3
- data/lib/oflow/actor.rb +3 -0
- data/lib/oflow/actors/httpserver.rb +3 -1
- data/lib/oflow/actors/log.rb +3 -2
- data/lib/oflow/actors/persister.rb +29 -6
- data/lib/oflow/actors/timer.rb +29 -12
- data/lib/oflow/box.rb +2 -2
- data/lib/oflow/env.rb +221 -15
- data/lib/oflow/flow.rb +217 -37
- data/lib/oflow/graffle.rb +293 -0
- data/lib/oflow/haserrorhandler.rb +3 -22
- data/lib/oflow/haslog.rb +21 -15
- data/lib/oflow/inspector.rb +18 -17
- data/lib/oflow/link.rb +11 -6
- data/lib/oflow/task.rb +134 -22
- data/lib/oflow/test/actorwrap.rb +1 -1
- data/lib/oflow/version.rb +1 -1
- data/test/actors/balancer_test.rb +17 -12
- data/test/actors/httpserver_test.rb +11 -10
- data/test/actors/log_test.rb +3 -6
- data/test/actors/merger_test.rb +23 -18
- data/test/actors/persister_test.rb +6 -8
- data/test/actors/timer_test.rb +63 -35
- data/test/actorwrap_test.rb +2 -6
- data/test/all_tests.rb +3 -7
- data/test/box_test.rb +4 -10
- data/test/flow_basic_test.rb +24 -22
- data/test/flow_cfg_error_test.rb +17 -13
- data/test/flow_linked_test.rb +146 -0
- data/test/flow_log_test.rb +43 -29
- data/test/flow_rescue_test.rb +41 -27
- data/test/flow_tracker_test.rb +26 -30
- data/test/helper.rb +15 -0
- data/test/task_test.rb +3 -7
- data/test/tracker_test.rb +3 -11
- metadata +5 -7
- data/lib/oflow/haslinks.rb +0 -68
- data/lib/oflow/hasname.rb +0 -31
- data/lib/oflow/hastasks.rb +0 -214
- data/test/flow_nest_test.rb +0 -215
data/test/flow_rescue_test.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: UTF-8
|
3
3
|
|
4
|
-
|
5
|
-
File.join(File.dirname(__FILE__), "../lib")
|
6
|
-
].each { |path| $: << path unless $:.include?(path) }
|
4
|
+
$: << File.dirname(__FILE__) unless $:.include? File.dirname(__FILE__)
|
7
5
|
|
8
|
-
require '
|
6
|
+
require 'helper'
|
9
7
|
require 'oflow'
|
10
8
|
|
11
9
|
require 'collector'
|
@@ -21,14 +19,15 @@ class Crash < ::OFlow::Actor
|
|
21
19
|
|
22
20
|
end # Crash
|
23
21
|
|
24
|
-
class FlowRescueTest < ::Test
|
22
|
+
class FlowRescueTest < ::MiniTest::Test
|
25
23
|
|
26
24
|
# Make sure the error handler works and forwards to the 'error' task if it
|
27
25
|
# exists.
|
28
26
|
def test_flow_rescue_task
|
27
|
+
env = ::OFlow::Env.new('')
|
29
28
|
trigger = nil
|
30
29
|
collector = nil
|
31
|
-
|
30
|
+
env.flow('rescue') { |f|
|
32
31
|
trigger = f.task('crash', Crash)
|
33
32
|
f.task(:collector, Collector) { |t|
|
34
33
|
collector = t.actor
|
@@ -40,21 +39,25 @@ class FlowRescueTest < ::Test::Unit::TestCase
|
|
40
39
|
t.link(nil, 'collector', 'log')
|
41
40
|
}
|
42
41
|
}
|
42
|
+
env.prepare()
|
43
|
+
env.start()
|
44
|
+
|
43
45
|
trigger.receive(:knock, ::OFlow::Box.new(7))
|
44
|
-
|
46
|
+
env.flush()
|
45
47
|
|
46
|
-
assert_equal(collector.collection.size
|
47
|
-
assert_equal(collector.collection[0][0].class
|
48
|
-
assert_equal(collector.collection[0][1]
|
48
|
+
assert_equal(1, collector.collection.size)
|
49
|
+
assert_equal(NoMethodError, collector.collection[0][0].class)
|
50
|
+
assert_equal('rescue:crash', collector.collection[0][1])
|
49
51
|
|
50
|
-
|
52
|
+
env.clear()
|
51
53
|
end
|
52
54
|
|
53
55
|
# Make sure the error handler on the flow is used to handle errors.
|
54
56
|
def test_flow_rescue_var
|
57
|
+
env = ::OFlow::Env.new('')
|
55
58
|
trigger = nil
|
56
59
|
collector = nil
|
57
|
-
|
60
|
+
env.flow('rescue') { |f|
|
58
61
|
trigger = f.task('crash', Crash)
|
59
62
|
f.error_handler = f.task(:collector, Collector) { |t|
|
60
63
|
collector = t.actor
|
@@ -63,51 +66,62 @@ class FlowRescueTest < ::Test::Unit::TestCase
|
|
63
66
|
t.link(nil, 'collector', 'log')
|
64
67
|
}
|
65
68
|
}
|
69
|
+
env.prepare()
|
70
|
+
env.start()
|
71
|
+
|
66
72
|
trigger.receive(:knock, ::OFlow::Box.new(7))
|
67
|
-
|
73
|
+
env.flush()
|
68
74
|
|
69
|
-
assert_equal(collector.collection.size
|
70
|
-
assert_equal(collector.collection[0][0].class
|
71
|
-
assert_equal(collector.collection[0][1]
|
75
|
+
assert_equal(1, collector.collection.size)
|
76
|
+
assert_equal(NoMethodError, collector.collection[0][0].class)
|
77
|
+
assert_equal('rescue:crash', collector.collection[0][1])
|
72
78
|
|
73
|
-
|
79
|
+
env.clear()
|
74
80
|
end
|
75
81
|
|
76
82
|
# Make sure the error handler on the flow is used to handle errors.
|
77
83
|
def test_flow_rescue_env
|
84
|
+
env = ::OFlow::Env.new('')
|
78
85
|
trigger = nil
|
79
86
|
collector = nil
|
80
|
-
|
87
|
+
env.flow('rescue') { |f|
|
81
88
|
trigger = f.task('crash', Crash)
|
82
|
-
|
89
|
+
env.error_handler = f.task(:collector, Collector) { |t|
|
83
90
|
collector = t.actor
|
84
91
|
}
|
85
92
|
f.task(:log, ::OFlow::Actors::Relay) { |t|
|
86
93
|
t.link(nil, 'collector', 'log')
|
87
94
|
}
|
88
95
|
}
|
96
|
+
env.prepare()
|
97
|
+
env.start()
|
98
|
+
|
89
99
|
trigger.receive(:knock, ::OFlow::Box.new(7))
|
90
|
-
|
100
|
+
env.flush()
|
91
101
|
|
92
102
|
assert_equal(1, collector.collection.size)
|
93
103
|
assert_equal(NoMethodError, collector.collection[0][0].class)
|
94
|
-
assert_equal('
|
104
|
+
assert_equal('rescue:crash', collector.collection[0][1])
|
95
105
|
|
96
|
-
|
106
|
+
env.clear()
|
97
107
|
end
|
98
108
|
|
99
109
|
# Make sure the default error handler on the flow passes a message to the log.
|
100
110
|
def test_flow_rescue_env_log
|
111
|
+
env = ::OFlow::Env.new('')
|
101
112
|
trigger = nil
|
102
113
|
collector = nil
|
103
|
-
|
114
|
+
env.flow('rescue') { |f|
|
104
115
|
trigger = f.task('crash', Crash)
|
105
|
-
|
116
|
+
env.log = f.task(:collector, Collector) { |t|
|
106
117
|
collector = t.actor
|
107
118
|
}
|
108
119
|
}
|
120
|
+
env.prepare()
|
121
|
+
env.start()
|
122
|
+
|
109
123
|
trigger.receive(:knock, ::OFlow::Box.new(7))
|
110
|
-
|
124
|
+
env.flush()
|
111
125
|
|
112
126
|
assert_equal(1, collector.collection.size)
|
113
127
|
assert_equal(["NoMethodError: undefined method `crash' for nil:NilClass",
|
@@ -115,9 +129,9 @@ class FlowRescueTest < ::Test::Unit::TestCase
|
|
115
129
|
"/task.rb:0:in `block in initialize'"],
|
116
130
|
simplify(collector.collection[0][0]))
|
117
131
|
|
118
|
-
assert_equal('
|
132
|
+
assert_equal('rescue:crash', collector.collection[0][1])
|
119
133
|
|
120
|
-
|
134
|
+
env.clear()
|
121
135
|
end
|
122
136
|
|
123
137
|
def simplify(bt)
|
data/test/flow_tracker_test.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: UTF-8
|
3
3
|
|
4
|
-
|
5
|
-
File.join(File.dirname(__FILE__), "../lib")
|
6
|
-
].each { |path| $: << path unless $:.include?(path) }
|
4
|
+
$: << File.dirname(__FILE__) unless $:.include? File.dirname(__FILE__)
|
7
5
|
|
8
|
-
require '
|
6
|
+
require 'helper'
|
9
7
|
require 'oflow'
|
10
8
|
|
11
9
|
require 'collector'
|
@@ -36,47 +34,45 @@ class Catch < ::OFlow::Actor
|
|
36
34
|
|
37
35
|
end # Catch
|
38
36
|
|
39
|
-
class FlowTrackerTest < ::Test
|
37
|
+
class FlowTrackerTest < ::MiniTest::Test
|
40
38
|
|
41
39
|
def test_flow_tracker
|
40
|
+
env = ::OFlow::Env.new('')
|
42
41
|
trigger = nil
|
43
42
|
catcher = nil
|
44
|
-
|
45
|
-
|
43
|
+
env.flow(:prime) { |f|
|
46
44
|
# starts off the process
|
47
45
|
trigger = f.task(:trigger, Throw) { |t|
|
48
|
-
t.link(nil, :
|
49
|
-
}
|
50
|
-
# a nested flow
|
51
|
-
f.flow(:deep) { |f2|
|
52
|
-
f2.route(nil, :one, nil)
|
53
|
-
f2.task(:one, Throw) { |t|
|
54
|
-
t.link(nil, :two, nil)
|
55
|
-
}
|
56
|
-
f2.task(:two, Throw) { |t|
|
57
|
-
t.link(nil, :flow, :bye)
|
58
|
-
}
|
59
|
-
f2.link(:bye, :out, nil)
|
46
|
+
t.link(nil, :one, nil, :deep)
|
60
47
|
}
|
61
|
-
f.task(:
|
48
|
+
f.task(:in, Throw) { |t|
|
62
49
|
t.link(nil, :done, nil)
|
63
50
|
}
|
64
51
|
catcher = f.task(:done, Catch)
|
65
52
|
}
|
53
|
+
env.flow(:deep) { |f|
|
54
|
+
f.task(:one, Throw) { |t|
|
55
|
+
t.link(nil, :two, nil)
|
56
|
+
}
|
57
|
+
f.task(:two, Throw) { |t|
|
58
|
+
t.link(nil, :in, :bye, :prime)
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
env.prepare()
|
63
|
+
env.start()
|
66
64
|
|
67
65
|
# run it and check the output
|
68
66
|
trigger.receive(:go, ::OFlow::Box.new(7, ::OFlow::Tracker.create('test')))
|
69
|
-
|
67
|
+
env.flush()
|
70
68
|
assert_equal(["test-",
|
71
|
-
":
|
72
|
-
":
|
73
|
-
"
|
74
|
-
":
|
75
|
-
":
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
::OFlow::Env.clear()
|
69
|
+
"prime:trigger-go",
|
70
|
+
"deep:one-",
|
71
|
+
"deep:two-",
|
72
|
+
"prime:in-bye",
|
73
|
+
"prime:done-"], catcher.actor.ball.tracker.track.map {|s| s.where })
|
74
|
+
|
75
|
+
env.clear()
|
80
76
|
end
|
81
77
|
|
82
78
|
end # FlowTrackerTest
|
data/test/helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
$VERBOSE = true
|
3
|
+
|
4
|
+
[ File.dirname(__FILE__),
|
5
|
+
File.join(File.dirname(__FILE__), "../lib"),
|
6
|
+
File.join(File.dirname(__FILE__), "../../oj/ext"),
|
7
|
+
File.join(File.dirname(__FILE__), "../../oj/lib"),
|
8
|
+
File.join(File.dirname(__FILE__), "../../ox/ext"),
|
9
|
+
File.join(File.dirname(__FILE__), "../../ox/lib"),
|
10
|
+
File.join(File.dirname(__FILE__), "../../oterm/lib"),
|
11
|
+
].each { |path| $: << path unless $:.include?(path) }
|
12
|
+
|
13
|
+
require 'minitest'
|
14
|
+
require 'minitest/unit'
|
15
|
+
require 'minitest/autorun'
|
data/test/task_test.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: UTF-8
|
3
3
|
|
4
|
-
|
5
|
-
File.join(File.dirname(__FILE__), "../lib")
|
6
|
-
].each { |path| $: << path unless $:.include?(path) }
|
7
|
-
|
8
|
-
require 'test/unit'
|
4
|
+
require 'helper'
|
9
5
|
require 'oflow'
|
10
6
|
|
11
7
|
class Gather < ::OFlow::Actor
|
@@ -27,7 +23,7 @@ class Gather < ::OFlow::Actor
|
|
27
23
|
end # Gather
|
28
24
|
|
29
25
|
|
30
|
-
class TaskTest < ::Test
|
26
|
+
class TaskTest < ::MiniTest::Test
|
31
27
|
|
32
28
|
def test_task_queue_count
|
33
29
|
task = ::OFlow::Task.new(nil, 'test', Gather)
|
@@ -72,7 +68,7 @@ class TaskTest < ::Test::Unit::TestCase
|
|
72
68
|
def test_task_raise_after_close
|
73
69
|
task = ::OFlow::Task.new(nil, 'test', Gather)
|
74
70
|
task.shutdown()
|
75
|
-
|
71
|
+
assert_raises(ThreadError) { task.start() }
|
76
72
|
end
|
77
73
|
|
78
74
|
def test_task_max_queue_count
|
data/test/tracker_test.rb
CHANGED
@@ -1,24 +1,16 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: UTF-8
|
3
3
|
|
4
|
-
|
5
|
-
# required. That can be set in the RUBYOPT environment variable.
|
6
|
-
# export RUBYOPT=-w
|
7
|
-
|
8
|
-
$VERBOSE = true
|
9
|
-
|
10
|
-
$: << File.join(File.dirname(__FILE__), "../lib")
|
11
|
-
|
12
|
-
require 'test/unit'
|
4
|
+
require 'helper'
|
13
5
|
require 'oflow'
|
14
6
|
|
15
|
-
class TrackerTest < ::Test
|
7
|
+
class TrackerTest < ::MiniTest::Test
|
16
8
|
|
17
9
|
def test_tracker_new
|
18
10
|
t = ::OFlow::Tracker.create('here')
|
19
11
|
t2 = ::OFlow::Tracker.create('here')
|
20
12
|
|
21
|
-
|
13
|
+
refute_equal(t.id, t2.id, 'id must be unique')
|
22
14
|
assert_equal('here', t.track[0].location)
|
23
15
|
end
|
24
16
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Ohler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Operations Workflow in Ruby. This implements a workflow/process flow
|
14
14
|
using multiple task nodes that each have their own queues and execution thread.
|
@@ -37,11 +37,9 @@ files:
|
|
37
37
|
- lib/oflow/env.rb
|
38
38
|
- lib/oflow/errors.rb
|
39
39
|
- lib/oflow/flow.rb
|
40
|
+
- lib/oflow/graffle.rb
|
40
41
|
- lib/oflow/haserrorhandler.rb
|
41
|
-
- lib/oflow/haslinks.rb
|
42
42
|
- lib/oflow/haslog.rb
|
43
|
-
- lib/oflow/hasname.rb
|
44
|
-
- lib/oflow/hastasks.rb
|
45
43
|
- lib/oflow/inspector.rb
|
46
44
|
- lib/oflow/link.rb
|
47
45
|
- lib/oflow/pattern.rb
|
@@ -64,17 +62,17 @@ files:
|
|
64
62
|
- test/collector.rb
|
65
63
|
- test/flow_basic_test.rb
|
66
64
|
- test/flow_cfg_error_test.rb
|
65
|
+
- test/flow_linked_test.rb
|
67
66
|
- test/flow_log_test.rb
|
68
|
-
- test/flow_nest_test.rb
|
69
67
|
- test/flow_rescue_test.rb
|
70
68
|
- test/flow_tracker_test.rb
|
69
|
+
- test/helper.rb
|
71
70
|
- test/stutter.rb
|
72
71
|
- test/task_test.rb
|
73
72
|
- test/tracker_test.rb
|
74
73
|
homepage: http://www.ohler.com/oflow
|
75
74
|
licenses:
|
76
75
|
- MIT
|
77
|
-
- GPL-3.0
|
78
76
|
metadata: {}
|
79
77
|
post_install_message:
|
80
78
|
rdoc_options:
|
data/lib/oflow/haslinks.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
|
2
|
-
module OFlow
|
3
|
-
|
4
|
-
# Adds support for Links. Used by Flow and Env.
|
5
|
-
module HasLinks
|
6
|
-
|
7
|
-
# Sets up the links attribute.
|
8
|
-
def init_links()
|
9
|
-
@links = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
# Creates a Link identified by the label that has a target Task or Flow and
|
13
|
-
# operation.
|
14
|
-
# @param label [Symbol|String] identifer of the Link
|
15
|
-
# @param target [Symbol|String] identifer of the target Task
|
16
|
-
# @param op [Symbol|String] operation to perform on the target Task
|
17
|
-
def link(label, target, op)
|
18
|
-
label = label.to_sym unless label.nil?
|
19
|
-
op = op.to_sym unless op.nil?
|
20
|
-
raise ConfigError.new("Link #{label} already exists.") unless @links[label].nil?
|
21
|
-
label = label.to_sym unless label.nil?
|
22
|
-
@links[label] = Link.new(target.to_sym, op)
|
23
|
-
end
|
24
|
-
|
25
|
-
# Attempts to find and resolve the Link identified by the label. Resolving a
|
26
|
-
# Link uses the target identifier to find the target Task and save that in
|
27
|
-
# the Link.
|
28
|
-
# @param label [Symbol|String] identifer of the Link
|
29
|
-
# @return [Link] returns the Link for the label
|
30
|
-
def resolve_link(label)
|
31
|
-
label = label.to_sym unless label.nil?
|
32
|
-
lnk = @links[label] || @links[nil]
|
33
|
-
return nil if lnk.nil?
|
34
|
-
set_link_target(lnk) if lnk.target.nil?
|
35
|
-
lnk
|
36
|
-
end
|
37
|
-
|
38
|
-
# Sets the target Task for a Link.
|
39
|
-
# @param lnk [Link] Link to find the target Task for.
|
40
|
-
def set_link_target(lnk)
|
41
|
-
if lnk.ingress
|
42
|
-
task = find_task(lnk.target_name)
|
43
|
-
else
|
44
|
-
task = @flow.find_task(lnk.target_name)
|
45
|
-
end
|
46
|
-
lnk.instance_variable_set(:@target, task)
|
47
|
-
end
|
48
|
-
|
49
|
-
# Attempts to find the Link identified by the label.
|
50
|
-
# @param label [Symbol|String] identifer of the Link
|
51
|
-
# @return [Link] returns the Link for the label
|
52
|
-
def find_link(label)
|
53
|
-
label = label.to_sym unless label.nil?
|
54
|
-
@links[label] || @links[nil]
|
55
|
-
end
|
56
|
-
|
57
|
-
# Returns the Links.
|
58
|
-
# @return [Hash] Hash of Links with the keys as Symbols that are the labels of the Links.
|
59
|
-
def links()
|
60
|
-
@links
|
61
|
-
end
|
62
|
-
|
63
|
-
def has_links?()
|
64
|
-
!@links.nil? && !@links.empty?
|
65
|
-
end
|
66
|
-
|
67
|
-
end # HasLinks
|
68
|
-
end # OFlow
|
data/lib/oflow/hasname.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
|
2
|
-
module OFlow
|
3
|
-
|
4
|
-
# Adds support for a name attribute and the ability to form full name for a
|
5
|
-
# named item.
|
6
|
-
module HasName
|
7
|
-
# The name.
|
8
|
-
attr_reader :name
|
9
|
-
|
10
|
-
# The containing Flow is used to support the full_name() method otherwise it
|
11
|
-
# just sets the name.
|
12
|
-
# @param flow [Flow|Env] containing Flow
|
13
|
-
# @param name [Symbol|String] base name
|
14
|
-
def init_name(flow, name)
|
15
|
-
@flow = flow
|
16
|
-
@name = name.to_sym
|
17
|
-
end
|
18
|
-
|
19
|
-
# Similar to a full file path. The full_name described the containment of
|
20
|
-
# the named item.
|
21
|
-
# @return [String] full name of item
|
22
|
-
def full_name()
|
23
|
-
if @flow.respond_to?(:full_name)
|
24
|
-
@flow.full_name() + ':' + @name.to_s
|
25
|
-
else
|
26
|
-
@name.to_s
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
end # HasName
|
31
|
-
end # OFlow
|