rbpm 0.0.2 → 0.0.3
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/LICENSE +147 -0
- data/README +30 -5
- data/bin/signal.sh +6 -0
- data/bin/start.sh +6 -0
- data/docs/rbpm-0.0.2-manual--wiki-snapshot.pdf +0 -0
- data/docs/todo.txt +7 -4
- data/lib/rbpm.rb +24 -598
- data/lib/rbpm/nodes.rb +109 -0
- data/lib/rbpm/persistence2.rb +265 -0
- data/lib/rbpm/persistence2_standalone.rb +46 -0
- data/lib/rbpm/token.rb +169 -0
- data/lib/rbpm/workflow.rb +457 -0
- data/lib/rbpm/workflow_managment.rb +57 -0
- data/test/rbpm_action_tests.rb +7 -2
- data/test/rbpm_call_tests.rb +7 -2
- data/test/rbpm_concurrency_fine_grained_graph_programming_sync_tests.rb +153 -0
- data/test/rbpm_condition_tests.rb +7 -2
- data/test/rbpm_ctxvars_tests.rb +7 -2
- data/test/rbpm_exceptions_tests.rb +7 -2
- data/test/rbpm_fork_join_tests.rb +7 -2
- data/test/rbpm_fs2_persistence_tests.rb +144 -0
- data/test/rbpm_simple_tests.rb +7 -2
- data/test/rbpm_state_tests.rb +7 -2
- data/test/rbpm_task_role_tests.rb +7 -2
- data/test/rbpm_transition_tests.rb +8 -3
- data/test/rbpm_versionning_tests.rb +13 -2
- data/test/ruby_lang_tests.rb +21 -0
- data/test/ts_all.rb +35 -25
- data/tutorial/README +65 -0
- data/tutorial/hello_world.rb +17 -0
- data/tutorial/rbpm_tutorial.rb +46 -0
- data/tutorial/sample_state_2_wf.rb +56 -0
- data/tutorial/signal_sample_state2.sh +1 -0
- data/tutorial/start_sample_state2.sh +1 -0
- data/tutorial/workflow_template.rb +73 -0
- metadata +22 -2
data/test/rbpm_simple_tests.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
|
3
3
|
begin
|
4
|
-
require '
|
4
|
+
require 'rubygems'
|
5
|
+
require_gem 'rbpm'
|
5
6
|
rescue LoadError
|
6
|
-
|
7
|
+
begin
|
8
|
+
require '../lib/rbpm'
|
9
|
+
rescue LoadError
|
10
|
+
require 'lib/rbpm'
|
11
|
+
end
|
7
12
|
end
|
8
13
|
|
9
14
|
#a simple join node (this test is older than rbpm 0.0.1 ;-)
|
data/test/rbpm_state_tests.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
|
3
3
|
begin
|
4
|
-
require '
|
4
|
+
require 'rubygems'
|
5
|
+
require_gem 'rbpm'
|
5
6
|
rescue LoadError
|
6
|
-
|
7
|
+
begin
|
8
|
+
require '../lib/rbpm'
|
9
|
+
rescue LoadError
|
10
|
+
require 'lib/rbpm'
|
11
|
+
end
|
7
12
|
end
|
8
13
|
|
9
14
|
class DemoWorkflow2 < Rbpm::Workflow
|
@@ -1,9 +1,14 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
|
3
3
|
begin
|
4
|
-
require '
|
4
|
+
require 'rubygems'
|
5
|
+
require_gem 'rbpm'
|
5
6
|
rescue LoadError
|
6
|
-
|
7
|
+
begin
|
8
|
+
require '../lib/rbpm'
|
9
|
+
rescue LoadError
|
10
|
+
require 'lib/rbpm'
|
11
|
+
end
|
7
12
|
end
|
8
13
|
|
9
14
|
#test, prototype, conceptual test - whatever
|
@@ -1,9 +1,14 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
|
3
3
|
begin
|
4
|
-
require '
|
4
|
+
require 'rubygems'
|
5
|
+
require_gem 'rbpm'
|
5
6
|
rescue LoadError
|
6
|
-
|
7
|
+
begin
|
8
|
+
require '../lib/rbpm'
|
9
|
+
rescue LoadError
|
10
|
+
require 'lib/rbpm'
|
11
|
+
end
|
7
12
|
end
|
8
13
|
|
9
14
|
$mylog = {}
|
@@ -102,7 +107,7 @@ class RbpmTransitionActionTests < Test::Unit::TestCase
|
|
102
107
|
["no", "yes"].each do |no_yes|
|
103
108
|
wf = TWf7.new
|
104
109
|
t = wf.start :my_cond => no_yes
|
105
|
-
assert_equal
|
110
|
+
assert_equal((no_yes + "_end").to_sym, t.node)
|
106
111
|
end
|
107
112
|
end
|
108
113
|
end
|
@@ -1,13 +1,20 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
|
3
3
|
begin
|
4
|
-
require '
|
4
|
+
require 'rubygems'
|
5
|
+
require_gem 'rbpm'
|
5
6
|
rescue LoadError
|
6
|
-
|
7
|
+
begin
|
8
|
+
require '../lib/rbpm'
|
9
|
+
rescue LoadError
|
10
|
+
require 'lib/rbpm'
|
11
|
+
end
|
7
12
|
end
|
8
13
|
|
9
14
|
module FooBarWorkflowVersion1
|
10
15
|
class FooBarWorkflow
|
16
|
+
def initialize(one_param)
|
17
|
+
end
|
11
18
|
def foo
|
12
19
|
"v1"
|
13
20
|
end
|
@@ -19,6 +26,8 @@ end
|
|
19
26
|
|
20
27
|
module FooBarWorkflowVersion3
|
21
28
|
class FooBarWorkflow
|
29
|
+
def initialize(one_param)
|
30
|
+
end
|
22
31
|
def foo
|
23
32
|
"v3"
|
24
33
|
end
|
@@ -27,6 +36,8 @@ end
|
|
27
36
|
|
28
37
|
module FooBarWorkflowVersion2
|
29
38
|
class FooBarWorkflow
|
39
|
+
def initialize(one_param)
|
40
|
+
end
|
30
41
|
def foo
|
31
42
|
"v2"
|
32
43
|
end
|
data/test/ruby_lang_tests.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'test/unit'
|
2
|
+
require 'monitor'
|
2
3
|
|
3
4
|
class FooClazz
|
4
5
|
def self.foo
|
@@ -62,8 +63,28 @@ module MyV2
|
|
62
63
|
end
|
63
64
|
ecode
|
64
65
|
|
66
|
+
def foo(&blk)
|
67
|
+
bar(&blk)
|
68
|
+
end
|
69
|
+
|
70
|
+
def bar(&blk)
|
71
|
+
blk.call "foobar"
|
72
|
+
end
|
73
|
+
|
65
74
|
class SimpleRubyLangTests < Test::Unit::TestCase
|
66
75
|
|
76
|
+
def test_sync_return
|
77
|
+
assert_equal 6, Monitor.new.synchronize { 6 }
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_block_stuff
|
81
|
+
result = nil
|
82
|
+
foo do |arg|
|
83
|
+
result = arg
|
84
|
+
end
|
85
|
+
assert_equal "foobar", result
|
86
|
+
end
|
87
|
+
|
67
88
|
def test_if_stuff
|
68
89
|
a = 1
|
69
90
|
a = 2 if false
|
data/test/ts_all.rb
CHANGED
@@ -1,34 +1,44 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
|
3
3
|
begin
|
4
|
-
require 'test/rbpm_action_tests'
|
5
|
-
require 'test/rbpm_ctxvars_tests
|
6
|
-
require 'test/rbpm_simple_tests
|
7
|
-
require 'test/rbpm_versionning_tests
|
8
|
-
require 'test/rbpm_call_tests
|
9
|
-
require 'test/rbpm_exceptions_tests
|
10
|
-
require 'test/rbpm_state_tests
|
11
|
-
require 'test/rbpm_condition_tests
|
12
|
-
require 'test/rbpm_fork_join_tests
|
13
|
-
require 'test/rbpm_transition_tests
|
14
|
-
require 'test/rbpm_task_role_tests
|
4
|
+
require 'test/rbpm_action_tests.rb'
|
5
|
+
require 'test/rbpm_ctxvars_tests'
|
6
|
+
require 'test/rbpm_simple_tests'
|
7
|
+
require 'test/rbpm_versionning_tests'
|
8
|
+
require 'test/rbpm_call_tests'
|
9
|
+
require 'test/rbpm_exceptions_tests'
|
10
|
+
require 'test/rbpm_state_tests'
|
11
|
+
require 'test/rbpm_condition_tests'
|
12
|
+
require 'test/rbpm_fork_join_tests'
|
13
|
+
require 'test/rbpm_transition_tests'
|
14
|
+
require 'test/rbpm_task_role_tests'
|
15
15
|
|
16
|
-
require 'test/
|
17
|
-
rescue LoadError
|
16
|
+
require 'test/rbpm_fs2_persistence_tests'
|
18
17
|
|
19
|
-
|
18
|
+
require 'test/rbpm_concurrency_fine_grained_graph_programming_sync_tests.rb'
|
19
|
+
|
20
|
+
require 'test/ruby_lang_tests'
|
21
|
+
rescue LoadError => e
|
22
|
+
#puts "Load Error: #{e}"
|
23
|
+
#puts "Load path: #{$LOAD_PATH.join(', ')}, Pwd=#{`pwd`}, ls test=#{`ls test`}"
|
24
|
+
|
25
|
+
#there must be a better way to handle this ;)
|
20
26
|
|
21
27
|
require 'rbpm_action_tests'
|
22
|
-
require 'rbpm_ctxvars_tests
|
23
|
-
require 'rbpm_simple_tests
|
24
|
-
require 'rbpm_versionning_tests
|
25
|
-
require 'rbpm_call_tests
|
26
|
-
require 'rbpm_exceptions_tests
|
27
|
-
require 'rbpm_state_tests
|
28
|
-
require 'rbpm_condition_tests
|
29
|
-
require 'rbpm_fork_join_tests
|
30
|
-
require 'rbpm_transition_tests
|
31
|
-
require 'rbpm_task_role_tests
|
28
|
+
require 'rbpm_ctxvars_tests'
|
29
|
+
require 'rbpm_simple_tests'
|
30
|
+
require 'rbpm_versionning_tests'
|
31
|
+
require 'rbpm_call_tests'
|
32
|
+
require 'rbpm_exceptions_tests'
|
33
|
+
require 'rbpm_state_tests'
|
34
|
+
require 'rbpm_condition_tests'
|
35
|
+
require 'rbpm_fork_join_tests'
|
36
|
+
require 'rbpm_transition_tests'
|
37
|
+
require 'rbpm_task_role_tests'
|
38
|
+
|
39
|
+
require 'rbpm_fs2_persistence_tests'
|
40
|
+
|
41
|
+
require 'rbpm_concurrency_fine_grained_graph_programming_sync_tests.rb'
|
32
42
|
|
33
|
-
require 'ruby_lang_tests
|
43
|
+
require 'ruby_lang_tests'
|
34
44
|
end
|
data/tutorial/README
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
README * RBPM TUTORIAL
|
2
|
+
|
3
|
+
(the following instructions assume that you have checked out rbpm from svn and
|
4
|
+
that you start all demos from the "tutorial" directory.)
|
5
|
+
|
6
|
+
hello_world.rb
|
7
|
+
A Hello World workflow (runnable)
|
8
|
+
shell> ruby hello_world.rb
|
9
|
+
|
10
|
+
rbpm_tutorial.rb
|
11
|
+
Another very simple workflow (runnable)
|
12
|
+
shell> ruby rbpm_tutorial.rb
|
13
|
+
|
14
|
+
workflow_template.rb
|
15
|
+
A nonsense-workflow which uses all available rbpm node types (not runnable)
|
16
|
+
|
17
|
+
sample_state_2_wf.rb
|
18
|
+
A more complex workflow: A fork node creates 4 child tokens. Two tokens
|
19
|
+
take transitions to a state node and the other 2 child tokens take
|
20
|
+
transitions to call node. Therefore, a sub workflow is called twice. The
|
21
|
+
root token of the sub workflow - which is instantiated twice - take
|
22
|
+
the transition to a state node. Thus, after start, there are 4 tokens
|
23
|
+
waiting in state nodes and need to be signaled. After all four
|
24
|
+
tokens have been signaled, the workflow's root token can take the
|
25
|
+
transition to the end node. Well, take a look at the code which is simpler
|
26
|
+
than this - bloody :) - description.
|
27
|
+
This is a demo of the file system based workflow instance persistence.
|
28
|
+
(sample_state_2_wf.rb is not runnable by itself - it's only the process definition)
|
29
|
+
|
30
|
+
signal_sample_state2.sh
|
31
|
+
Creates and starts a new workflow instance (sample_state_2_wf.rb). The workflow
|
32
|
+
instance will be persisted, because at least one token is waiting in
|
33
|
+
a state node.
|
34
|
+
|
35
|
+
start_sample_state2.sh
|
36
|
+
Sends a signal to a token (of a persisted workflow) waiting in a state node.
|
37
|
+
Every signal_sample_state2.sh call has to be followed by
|
38
|
+
4 start_sample_state2.sh in order to complete the workflow. This script
|
39
|
+
takes a token id as parameter.
|
40
|
+
|
41
|
+
shell> ./start_sample_state2.sh
|
42
|
+
arriving in :decision of SampleState2Workflow, token.ref=1
|
43
|
+
arriving in :no_call (state) of SampleState2Workflow, token.ref=1
|
44
|
+
arriving in :decision of SampleState2Workflow, token.ref=2
|
45
|
+
arriving in :state (state) of SampleState2SubWorkflow, token.ref=5
|
46
|
+
arriving in :decision of SampleState2Workflow, token.ref=3
|
47
|
+
arriving in :state (state) of SampleState2SubWorkflow, token.ref=6
|
48
|
+
arriving in :decision of SampleState2Workflow, token.ref=4
|
49
|
+
arriving in :no_call (state) of SampleState2Workflow, token.ref=4
|
50
|
+
0
|
51
|
+
|
52
|
+
shell> ./signal_sample_state2.sh 1
|
53
|
+
arriving in :join of SampleState2Workflow, token.ref=1
|
54
|
+
|
55
|
+
shell> ./signal_sample_state2.sh 5
|
56
|
+
arriving in :end of SampleState2SubWorkflow, token.ref=5
|
57
|
+
arriving in :join of SampleState2Workflow, token.ref=2
|
58
|
+
|
59
|
+
shell> ./signal_sample_state2.sh 6
|
60
|
+
arriving in :end of SampleState2SubWorkflow, token.ref=6
|
61
|
+
arriving in :join of SampleState2Workflow, token.ref=3
|
62
|
+
|
63
|
+
shell> ./signal_sample_state2.sh 4
|
64
|
+
arriving in :join of SampleState2Workflow, token.ref=4
|
65
|
+
arriving in :end of SampleState2Workflow, token.ref=0
|
@@ -0,0 +1,17 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
require_gem 'rbpm', '>= 0.0.2'
|
4
|
+
rescue LoadError
|
5
|
+
require '../lib/rbpm'
|
6
|
+
end
|
7
|
+
|
8
|
+
class HelloWorldWorkflow < Rbpm::Workflow
|
9
|
+
start_node :start, :trans => :end
|
10
|
+
end_node :end
|
11
|
+
|
12
|
+
leave(:start) do
|
13
|
+
puts "Hello World"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
HelloWorldWorkflow.new.start
|
@@ -0,0 +1,46 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
require_gem 'rbpm', '>= 0.0.2'
|
4
|
+
puts "rbpm.gem loaded"
|
5
|
+
rescue LoadError
|
6
|
+
require '../lib/rbpm'
|
7
|
+
puts "rbpm.local loaded"
|
8
|
+
end
|
9
|
+
|
10
|
+
class TutorialDemoWorkflow < Rbpm::Workflow
|
11
|
+
|
12
|
+
start_node :start, :trans => :hello_wait
|
13
|
+
state_node :hello_wait, :trans => :end
|
14
|
+
end_node :end
|
15
|
+
|
16
|
+
enter(:start) do |token,caller|
|
17
|
+
puts "Entering hello node"
|
18
|
+
end
|
19
|
+
|
20
|
+
enter(:hello_wait) do |token,caller|
|
21
|
+
puts "Entering hello_wait node"
|
22
|
+
end
|
23
|
+
|
24
|
+
enter(:end) do |token,caller|
|
25
|
+
puts "Entering end node"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
puts "I will start the workflow now..."
|
30
|
+
|
31
|
+
wf = Rbpm::WorkflowVersionManager.create_workflow_instance("TutorialDemoWorkflow")
|
32
|
+
t = wf.start
|
33
|
+
|
34
|
+
puts "And now I will send a signal to the workflow's root token..."
|
35
|
+
|
36
|
+
t.signal
|
37
|
+
|
38
|
+
puts "End"
|
39
|
+
|
40
|
+
#Expected output:
|
41
|
+
# I will start the workflow now...
|
42
|
+
# Entering hello node
|
43
|
+
# Entering hello_wait node
|
44
|
+
# And now I will send a signal to the workflow's root token...
|
45
|
+
# Entering end node
|
46
|
+
# End
|
@@ -0,0 +1,56 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
require_gem 'rbpm', '>= 0.0.3'
|
4
|
+
rescue LoadError
|
5
|
+
require '../lib/rbpm'
|
6
|
+
end
|
7
|
+
|
8
|
+
class SampleState2SubWorkflow < Rbpm::Workflow
|
9
|
+
start_node :start, :trans => :state
|
10
|
+
state_node :state, :trans => :end
|
11
|
+
end_node :end
|
12
|
+
|
13
|
+
enter(:state) do |token, caller|
|
14
|
+
$stderr.puts "arriving in :state (state) of SampleState2SubWorkflow, token.ref=#{token.ref}"
|
15
|
+
end
|
16
|
+
|
17
|
+
enter(:end) do |token, caller|
|
18
|
+
$stderr.puts "arriving in :end of SampleState2SubWorkflow, token.ref=#{token.ref}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class SampleState2Workflow < Rbpm::Workflow
|
23
|
+
start_node :start, :trans => :fork
|
24
|
+
fork_node :fork, :trans => :decision,
|
25
|
+
:children_ctx => :sub_ctxs,
|
26
|
+
:on_enter => lambda { |token,caller| token[:sub_ctxs] = [{:call => false}, {:call => true}, {:call => true}, {:call => false}] }
|
27
|
+
node :decision,
|
28
|
+
:call_trans => :call,
|
29
|
+
:call_trans_cond => "token[:call]",
|
30
|
+
:no_call_trans => :no_call,
|
31
|
+
:no_call_trans_cond => "not token[:call]"
|
32
|
+
call_node :call,
|
33
|
+
:workflow => :SampleState2SubWorkflow,
|
34
|
+
:call_in => {},
|
35
|
+
:call_out => {},
|
36
|
+
:trans => :join
|
37
|
+
state_node :no_call, :trans => :join
|
38
|
+
join_node :join, :trans => :end
|
39
|
+
end_node :end
|
40
|
+
|
41
|
+
enter(:decision) do |token, caller|
|
42
|
+
$stderr.puts "arriving in :decision of SampleState2Workflow, token.ref=#{token.ref}"
|
43
|
+
end
|
44
|
+
|
45
|
+
enter(:no_call) do |token, caller|
|
46
|
+
$stderr.puts "arriving in :no_call (state) of SampleState2Workflow, token.ref=#{token.ref}"
|
47
|
+
end
|
48
|
+
|
49
|
+
enter(:join) do |token, caller|
|
50
|
+
$stderr.puts "arriving in :join of SampleState2Workflow, token.ref=#{token.ref}"
|
51
|
+
end
|
52
|
+
|
53
|
+
enter(:end) do |token, caller|
|
54
|
+
$stderr.puts "arriving in :end of SampleState2Workflow, token.ref=#{token.ref}"
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
./../bin/signal.sh sample_state_2_wf.rb $1
|
@@ -0,0 +1 @@
|
|
1
|
+
./../bin/start.sh sample_state_2_wf.rb SampleState2Workflow
|
@@ -0,0 +1,73 @@
|
|
1
|
+
begin
|
2
|
+
require '../lib/rbpm'
|
3
|
+
rescue LoadError
|
4
|
+
require 'rubygems'
|
5
|
+
require_gem 'rbpm', '>= 0.0.2' #0.0.2 for transit and for Bpm:: module
|
6
|
+
end
|
7
|
+
|
8
|
+
module TemplateWorkflowVersion1
|
9
|
+
class TemplateWorkflow < Rbpm::Workflow
|
10
|
+
#nodes and transitions
|
11
|
+
|
12
|
+
node :node_name,
|
13
|
+
:trans => :target_node_name, #(shortcut for) :default_trans
|
14
|
+
:trans_cond => "ruby expr.", #(optional) default="true"
|
15
|
+
:trans_name_trans => :target_node_name, #2nd transition
|
16
|
+
:trans_name_trans_cond => "ruby expr.", #2nd transition's condition
|
17
|
+
:exception => :node_name #(optional)
|
18
|
+
|
19
|
+
node :my_decision,
|
20
|
+
:success_trans => :success,
|
21
|
+
:success_trans_cond => "token[:bytes_transferred] > 1024",
|
22
|
+
:repeat_trans => :try_again,
|
23
|
+
:repeat_trans_cond => "token[:bytes_transferred] > 0 and token[:bytes_transferred] < 1024",
|
24
|
+
:failed_trans => :failed,
|
25
|
+
:failed_trans_cond => "token[:bytes_transferred] == 0"
|
26
|
+
|
27
|
+
start_node :start_node_name, :trans => :target_node_name #only one start_node per workflow
|
28
|
+
|
29
|
+
end_node :end_node_name #outgoing transitions not allowed
|
30
|
+
|
31
|
+
state_node :state_node_name, :trans => :target_node_name
|
32
|
+
|
33
|
+
fork_node :fork_node_name,
|
34
|
+
:children_ctx => :children_ctx_token_variable_name, #children_ctx token var stores initial vars of all children
|
35
|
+
:trans => :target_node_name #only one transition (default_trans) is supported
|
36
|
+
|
37
|
+
join_node :join_node_name, :trans => :end
|
38
|
+
|
39
|
+
call_node :call_node_name,
|
40
|
+
:workflow => :ChildWorkflowClassName,
|
41
|
+
:workflow_version => 1, #(optional) version number or :latest
|
42
|
+
:call_in => {:parent_wf_token_var => :child_wf_token_var}, #input-param mapping
|
43
|
+
:call_out => {:child_wf_token_var => :parent_wf_token_var}, #output-param mapping
|
44
|
+
:trans => :end #only one transition (default_trans) is supported
|
45
|
+
|
46
|
+
#event actions
|
47
|
+
|
48
|
+
enter(:node_name) do |token,caller|
|
49
|
+
#modify token variables, call business delegate methods, ...
|
50
|
+
end
|
51
|
+
|
52
|
+
leave(:node_name) do |token,caller|
|
53
|
+
#modify token variables, call business delegate methods, ...
|
54
|
+
end
|
55
|
+
|
56
|
+
transit(:my_decision, :success) do |token,caller|
|
57
|
+
$mylog[:transit] = "foo"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#class ForkJoinDemoWorkflow < Rbpm::Workflow
|
63
|
+
# start_node :start, :trans => :fork
|
64
|
+
# fork_node :fork,
|
65
|
+
# :trans => :join,
|
66
|
+
# :children_ctx => :sub_ctxs,
|
67
|
+
# :on_enter => lambda { |token,caller| token[:sub_ctxs] = [{:msg => "Hello"}, {:msg => "World"}] }
|
68
|
+
# join_node :join,
|
69
|
+
# :trans => :end,
|
70
|
+
# :on_enter => lambda { |token,caller| puts token[:msg] }
|
71
|
+
# end_node :end
|
72
|
+
#end
|
73
|
+
#ForkJoinDemoWorkflow.new.start #output Hello\nWorld
|