-
Notifications
You must be signed in to change notification settings - Fork 0
/
quickstart.rb
155 lines (117 loc) · 3.48 KB
/
quickstart.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
require 'rufus-json/automatic'
require 'ruote'
require 'ruote/storage/fs_storage'
#
# Preparing the engine
# The ruote onion:
# * storage at the core
# * a worker tied to the storage
# * a dashboard with all the levers as the outer layer
#
# This storage uses the filesystem to persist all the ruote messages, workitems,
# etc...
#
# Placing the onion in a convenient 'ruote' local variable.
ruote = Ruote::Dashboard.new(
Ruote::Worker.new(
Ruote::FsStorage.new('ruote_work')))
ruote.noisy = ENV['NOISY'] == 'true'
#
# if the env variable NOISY is set to 'true', the engine activity will
# be detailed on $stdout.
#
# Defining participants
# Three kinds of participants, logistics, scouts and leaders.
# Logistics prepare the materail for scouts, scouts go out and count birds,
# leaders compile a report
class Logistics < Ruote::Participant
def on_workitem
puts
puts "prepare for a #{workitem.fields['bird']} photo hunt..."
puts
workitem.fields['spotted'] = []
reply
end
end
class Scout < Ruote::Participant
def on_workitem
sleep(rand)
result = [ workitem.participant_name, (20 * rand + 1).to_i ]
workitem.fields['spotted'] << result
p result
reply
#
# participant work done, call #reply to give back the workitem to ruote
# and let the flow move on
end
end
class Leader < Ruote::Participant
def on_workitem
workitem.fields['total'] = workitem.fields['spotted'].inject(0) { |t, f|
t + f[1]
}
puts
puts "bird: " + workitem.fields['bird']
puts "spotted: " + workitem.fields['spotted'].inspect
puts "total: " + workitem.fields['total'].inspect
puts
# TODO: upload to Google spreadsheet
reply
end
end
#
# Registering participants
# Mapping participant names to participant classes.
ruote.register /^scout_/, Scout
ruote.register /^leader_/, Leader
ruote.register 'logistics', Logistics
#
# Defining a process
# This is the Doug team's process, simply send out Alice, Bob and Charly to
# count the birds and then Doug compiles the report.
#
# The merge_type concats the workitem fields that are arrays. In our case
# the resulting 'spotted' field is the concatenation of the three 'spotted'
# fields emitted by each scout.
# The process definition is written in 'radial', a mini language understood
# by ruote.
pdef = %q{
define
logistics
concurrence merge_type: concat
scout_alice
scout_bob
scout_charly
leader_doug
}
# If you hate significant indentation, you can use plain Ruby, thanks to
# Ruote.define:
#pdef = Ruote.define do
# concurrence :merge_type => :concat do
# scout_alice
# scout_bob
# scout_charly
# end
# leader_doug
#end
#
# Launching, creating a process instance
# For this quickstart, we only launch 1 instance of the process (and wait
# for it to end).
#
# The #launch method accepts a process definition and an optional list of
# initial workitem fields.
#
# Ruote is mostly a process definition interpreter. You can call launch
# multiple times with different combinations of definitions and fields and
# ruote will run multiple process/workflow instances.
wfid = ruote.launch(
pdef,
'bird' => %w[ thrush cardinal dodo ].shuffle.first)
ruote.wait_for(wfid)
#
# Blocks current thread until our process instance terminates
#
# This wait_for is mainly used in tests (and demos), you usually don't
# want to wait_for flows, they are asynchronous beasts and they get back
# to you (via a participant or a process observer)