swarm 0.3.0 → 0.4.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.
- checksums.yaml +5 -5
- data/.ruby-version +1 -1
- data/Gemfile +2 -0
- data/Rakefile +3 -1
- data/bin/console +1 -0
- data/lib/swarm/engine/{base/job.rb → job.rb} +2 -0
- data/lib/swarm/engine/{base/queue.rb → queue.rb} +7 -5
- data/lib/swarm/engine/volatile/job.rb +6 -2
- data/lib/swarm/engine/volatile/queue.rb +7 -4
- data/lib/swarm/engine/worker/command.rb +5 -1
- data/lib/swarm/engine/worker.rb +22 -19
- data/lib/swarm/evaluation/expression_evaluator.rb +21 -14
- data/lib/swarm/expression.rb +8 -6
- data/lib/swarm/expressions/activity_expression.rb +2 -0
- data/lib/swarm/expressions/branch_expression.rb +12 -9
- data/lib/swarm/expressions/concurrence_expression.rb +8 -5
- data/lib/swarm/expressions/conditional_expression.rb +4 -2
- data/lib/swarm/expressions/sequence_expression.rb +4 -2
- data/lib/swarm/expressions/subprocess_expression.rb +4 -1
- data/lib/swarm/hive.rb +9 -16
- data/lib/swarm/hive_dweller.rb +69 -38
- data/lib/swarm/observers/base.rb +3 -1
- data/lib/swarm/observers/logger.rb +40 -0
- data/lib/swarm/participant.rb +3 -1
- data/lib/swarm/participants/storage_participant.rb +6 -4
- data/lib/swarm/participants/trace_participant.rb +2 -0
- data/lib/swarm/pollen/parser.rb +48 -44
- data/lib/swarm/pollen/reader.rb +5 -3
- data/lib/swarm/pollen/transformer.rb +30 -24
- data/lib/swarm/process.rb +21 -14
- data/lib/swarm/process_definition.rb +13 -10
- data/lib/swarm/router.rb +8 -6
- data/lib/swarm/storage/hash_storage.rb +3 -1
- data/lib/swarm/storage/key_value_storage.rb +27 -13
- data/lib/swarm/storage/redis_storage.rb +4 -2
- data/lib/swarm/storage.rb +3 -1
- data/lib/swarm/stored_workitem.rb +4 -2
- data/lib/swarm/support.rb +13 -16
- data/lib/swarm/version.rb +3 -1
- data/lib/swarm.rb +4 -2
- data/swarm.gemspec +7 -5
- metadata +51 -24
- data/lib/swarm/evaluation/workitem_context.rb +0 -17
data/lib/swarm/hive_dweller.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Swarm
|
2
4
|
class HiveDweller
|
5
|
+
class MissingTypeError < StandardError; end
|
3
6
|
class RecordNotFoundError < StandardError; end
|
4
7
|
|
5
8
|
attr_reader :hive, :id
|
@@ -23,6 +26,7 @@ module Swarm
|
|
23
26
|
unless unknown_arguments.empty?
|
24
27
|
raise ArgumentError, "unknown keywords: #{unknown_arguments.join(', ')}"
|
25
28
|
end
|
29
|
+
|
26
30
|
args.each do |key, value|
|
27
31
|
change_attribute(key, value, record: record_changes)
|
28
32
|
end
|
@@ -55,7 +59,7 @@ module Swarm
|
|
55
59
|
def save
|
56
60
|
if new? || changed?
|
57
61
|
@id ||= Swarm::Support.uuid_with_timestamp
|
58
|
-
storage[storage_id] = to_hash.merge(:
|
62
|
+
storage[storage_id] = to_hash.merge(updated_at: Time.now)
|
59
63
|
reload!
|
60
64
|
end
|
61
65
|
self
|
@@ -69,8 +73,8 @@ module Swarm
|
|
69
73
|
|
70
74
|
def to_hash
|
71
75
|
hsh = {
|
72
|
-
:
|
73
|
-
:
|
76
|
+
id: id,
|
77
|
+
type: self.class.name
|
74
78
|
}
|
75
79
|
hsh.merge(attributes)
|
76
80
|
end
|
@@ -80,8 +84,8 @@ module Swarm
|
|
80
84
|
self.class.columns.each do |column|
|
81
85
|
instance_variable_set(:"@#{column}", hsh[column.to_s])
|
82
86
|
end
|
83
|
-
self.class.associations.
|
84
|
-
instance_variable_set(:"@#{
|
87
|
+
self.class.associations.each_key do |name|
|
88
|
+
instance_variable_set(:"@#{name}", nil)
|
85
89
|
end
|
86
90
|
@changed_attributes = {}
|
87
91
|
self
|
@@ -95,53 +99,70 @@ module Swarm
|
|
95
99
|
def inherited(subclass)
|
96
100
|
super
|
97
101
|
subclass.instance_variable_set(:@columns, [])
|
98
|
-
subclass.instance_variable_set(:@associations,
|
102
|
+
subclass.instance_variable_set(:@associations, {})
|
99
103
|
subclass.set_columns :updated_at, :created_at
|
100
104
|
end
|
101
105
|
|
102
106
|
def set_columns(*args)
|
103
107
|
args.each do |arg|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
val
|
114
|
-
}
|
108
|
+
define_setter(arg)
|
109
|
+
define_getter(arg)
|
110
|
+
end
|
111
|
+
@columns |= args
|
112
|
+
end
|
113
|
+
|
114
|
+
def define_setter(arg)
|
115
|
+
define_method("#{arg}=") do |value|
|
116
|
+
change_attribute(arg, value)
|
115
117
|
end
|
116
|
-
@columns = @columns | args
|
117
118
|
end
|
118
119
|
|
119
|
-
def
|
120
|
-
define_method(
|
121
|
-
|
120
|
+
def define_getter(arg)
|
121
|
+
define_method(arg) {
|
122
|
+
val = instance_variable_get(:"@#{arg}")
|
123
|
+
if /_at$/.match(arg) && val.is_a?(String)
|
124
|
+
val = Time.parse(val)
|
125
|
+
end
|
126
|
+
val
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
def one_to_many(association_name, class_name: nil, foreign_key: nil)
|
131
|
+
define_method(association_name) do
|
132
|
+
memo = instance_variable_get(:"@#{association_name}")
|
122
133
|
memo || begin
|
123
134
|
associations = hive.storage.load_associations(
|
124
|
-
|
135
|
+
association_name, owner: self, class_name: class_name || association_name, foreign_key: foreign_key
|
125
136
|
)
|
126
|
-
entities = associations.map { |association|
|
127
|
-
instance_variable_set(:"@#{
|
137
|
+
entities = associations.map { |association| self.class.reify_from_hash(association, hive: hive) }
|
138
|
+
instance_variable_set(:"@#{association_name}", entities)
|
128
139
|
end
|
129
140
|
end
|
130
|
-
|
141
|
+
define_method(:"add_to_#{association_name}") do |associated|
|
142
|
+
hive.storage.add_association(
|
143
|
+
association_name, associated, owner: self, class_name: class_name || association_name, foreign_key: foreign_key
|
144
|
+
)
|
145
|
+
end
|
146
|
+
@associations[association_name] = {
|
147
|
+
type: :one_to_many, class_name: class_name || association_name, foreign_key: foreign_key
|
148
|
+
}
|
131
149
|
end
|
132
150
|
|
133
|
-
def many_to_one(
|
134
|
-
define_method(
|
135
|
-
memo = instance_variable_get(:"@#{
|
151
|
+
def many_to_one(association_name, class_name: nil, key: nil)
|
152
|
+
define_method(association_name) do
|
153
|
+
memo = instance_variable_get(:"@#{association_name}")
|
136
154
|
memo || begin
|
137
|
-
key ||= :"#{
|
138
|
-
associated_id =
|
155
|
+
key ||= :"#{association_name}_id"
|
156
|
+
associated_id = send(key)
|
139
157
|
return nil unless associated_id
|
140
|
-
|
141
|
-
|
158
|
+
|
159
|
+
klass = Swarm::Support.constantize((class_name || association_name).to_s)
|
160
|
+
instance_variable_set(:"@#{association_name}", klass.fetch(associated_id, hive: hive))
|
142
161
|
end
|
143
162
|
end
|
144
|
-
@associations
|
163
|
+
@associations[association_name] = {
|
164
|
+
type: :many_to_one, class_name: class_name || association_name, key: key
|
165
|
+
}
|
145
166
|
end
|
146
167
|
|
147
168
|
def create(hive: Hive.default, **args)
|
@@ -153,7 +174,7 @@ module Swarm
|
|
153
174
|
end
|
154
175
|
|
155
176
|
def storage_id_for_key(key)
|
156
|
-
if key.match(/^#{storage_type}
|
177
|
+
if key.match(/^#{storage_type}:/)
|
157
178
|
key
|
158
179
|
else
|
159
180
|
"#{storage_type}:#{key}"
|
@@ -169,18 +190,19 @@ module Swarm
|
|
169
190
|
|
170
191
|
def fetch(key, hive: Hive.default)
|
171
192
|
hsh = hive.storage[storage_id_for_key(key)].dup
|
172
|
-
|
193
|
+
reify_from_hash(hsh, hive: hive)
|
173
194
|
end
|
174
195
|
|
175
196
|
def ids(hive: Hive.default)
|
176
197
|
hive.storage.ids_for_type(storage_type)
|
177
198
|
end
|
178
199
|
|
179
|
-
def each(hive: Hive.default, subtypes: true
|
200
|
+
def each(hive: Hive.default, subtypes: true)
|
180
201
|
return to_enum(__method__, hive: hive, subtypes: subtypes) unless block_given?
|
202
|
+
|
181
203
|
ids(hive: hive).each do |id|
|
182
204
|
object = fetch(id, hive: hive)
|
183
|
-
if (subtypes && object.is_a?(self)) || object.
|
205
|
+
if (subtypes && object.is_a?(self)) || object.instance_of?(self)
|
184
206
|
yield object
|
185
207
|
end
|
186
208
|
end
|
@@ -188,9 +210,18 @@ module Swarm
|
|
188
210
|
|
189
211
|
def all(hive: Hive.default, subtypes: true)
|
190
212
|
hive.storage.all_of_type(storage_type, subtypes: subtypes).map { |hsh|
|
191
|
-
|
213
|
+
reify_from_hash(hsh.dup, hive: hive)
|
192
214
|
}
|
193
215
|
end
|
216
|
+
|
217
|
+
def reify_from_hash(hsh, hive: Hive.default)
|
218
|
+
Support.symbolize_keys!(hsh)
|
219
|
+
raise MissingTypeError, hsh.inspect unless hsh[:type]
|
220
|
+
|
221
|
+
Swarm::Support.constantize(hsh.delete(:type)).new_from_storage(
|
222
|
+
**hsh.merge(hive: hive)
|
223
|
+
)
|
224
|
+
end
|
194
225
|
end
|
195
226
|
end
|
196
227
|
end
|
data/lib/swarm/observers/base.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module Swarm
|
6
|
+
module Observers
|
7
|
+
class Logger < Base
|
8
|
+
attr_reader :initial_workitem
|
9
|
+
|
10
|
+
def before_action
|
11
|
+
return unless object
|
12
|
+
|
13
|
+
@initial_workitem = object.workitem
|
14
|
+
end
|
15
|
+
|
16
|
+
def log_entry
|
17
|
+
"[#{Time.now}]: #{action}; #{object_string}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def after_action
|
21
|
+
puts log_entry
|
22
|
+
end
|
23
|
+
|
24
|
+
def object_string
|
25
|
+
return "No object" unless object
|
26
|
+
|
27
|
+
object.reload!
|
28
|
+
string = if object.is_a?(Swarm::Expression)
|
29
|
+
"#{object.position}: #{object.command} #{object.arguments}"
|
30
|
+
elsif object.is_a?(Swarm::Process)
|
31
|
+
object.process_definition_name.to_s
|
32
|
+
end
|
33
|
+
if object.workitem != initial_workitem
|
34
|
+
string += "; #{object.workitem}"
|
35
|
+
end
|
36
|
+
string
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/swarm/participant.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "../participant"
|
2
4
|
|
3
5
|
module Swarm
|
4
6
|
class StorageParticipant < Participant
|
5
7
|
def work
|
6
|
-
StoredWorkitem.create(
|
7
|
-
:
|
8
|
-
:
|
9
|
-
|
8
|
+
StoredWorkitem.create(
|
9
|
+
hive: hive,
|
10
|
+
expression_id: expression.id
|
11
|
+
)
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
data/lib/swarm/pollen/parser.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "parslet"
|
2
4
|
|
3
5
|
module Swarm
|
@@ -7,88 +9,90 @@ module Swarm
|
|
7
9
|
spaces? >> atom >> spaces?
|
8
10
|
end
|
9
11
|
|
10
|
-
rule(:eol)
|
11
|
-
rule(:whitespace)
|
12
|
-
rule(:spaces)
|
13
|
-
rule(:spaces?)
|
14
|
-
rule(:comma)
|
12
|
+
rule(:eol) do optionally_spaced(match['\n']).repeat(1) end
|
13
|
+
rule(:whitespace) do match('\s').repeat(0) end
|
14
|
+
rule(:spaces) do match[' \t'].repeat(1) end
|
15
|
+
rule(:spaces?) do spaces.maybe end
|
16
|
+
rule(:comma) do optionally_spaced(str(',')) end
|
15
17
|
|
16
|
-
rule(:integer)
|
18
|
+
rule(:integer) do
|
17
19
|
match['0-9'].repeat(1).as(:integer)
|
18
|
-
|
20
|
+
end
|
19
21
|
|
20
|
-
rule(:float)
|
22
|
+
rule(:float) do
|
21
23
|
(match['0-9'].repeat(1) >> str('.') >> match['0-9'].repeat(1)).as(:float)
|
22
|
-
|
24
|
+
end
|
23
25
|
|
24
|
-
rule(:line)
|
26
|
+
rule(:line) do
|
25
27
|
(match['\n'].absent? >> any).repeat(1).as(:line)
|
26
|
-
|
28
|
+
end
|
27
29
|
|
28
|
-
rule(:string)
|
30
|
+
rule(:string) do
|
29
31
|
(str("'") | str('"')).capture(:q) >>
|
30
32
|
(str('\\') >> any |
|
31
|
-
dynamic { |
|
32
|
-
).repeat.as(:string) >> dynamic { |
|
33
|
-
|
33
|
+
dynamic { |_s, c| str(c.captures[:q]) }.absent? >> any
|
34
|
+
).repeat.as(:string) >> dynamic { |_s, c| str(c.captures[:q]) }
|
35
|
+
end
|
34
36
|
|
35
|
-
rule(:colon_pair)
|
37
|
+
rule(:colon_pair) do
|
36
38
|
token.as(:key) >> str(':') >> spaces? >> string.as(:value)
|
37
|
-
|
39
|
+
end
|
38
40
|
|
39
|
-
rule(:symbol)
|
40
|
-
rule(:token)
|
41
|
+
rule(:symbol) do str(':') >> token.as(:symbol) end
|
42
|
+
rule(:token) do (match('[a-z_]') >> match('[a-zA-Z0-9_]').repeat(0)).as(:token) end
|
41
43
|
|
42
|
-
rule(:rocket_pair)
|
44
|
+
rule(:rocket_pair) do
|
43
45
|
(symbol | string).as(:key) >> optionally_spaced(str('=>')) >> string.as(:value)
|
44
|
-
|
46
|
+
end
|
45
47
|
|
46
|
-
rule(:key_value_pair)
|
48
|
+
rule(:key_value_pair) do rocket_pair | colon_pair end
|
47
49
|
|
48
|
-
rule(:key_value_list)
|
50
|
+
rule(:key_value_list) do
|
49
51
|
key_value_pair >> (comma >> key_value_pair).repeat(0)
|
50
|
-
|
52
|
+
end
|
51
53
|
|
52
|
-
rule(:arguments)
|
53
|
-
key_value_list.as(:arguments) |
|
54
|
-
|
54
|
+
rule(:arguments) do
|
55
|
+
key_value_list.as(:arguments) | (
|
56
|
+
string.as(:text_argument) >> (comma >> key_value_list.as(:arguments)).maybe
|
57
|
+
)
|
58
|
+
end
|
55
59
|
|
56
|
-
rule(:reserved_word)
|
57
|
-
%w
|
58
|
-
|
60
|
+
rule(:reserved_word) do
|
61
|
+
%w[if unless else end].map { |w| str(w) }.reduce(:|)
|
62
|
+
end
|
59
63
|
|
60
|
-
rule(:expression)
|
64
|
+
rule(:expression) do
|
61
65
|
reserved_word.absent? >> token.as(:command) >> (spaces >> arguments).maybe
|
62
|
-
|
66
|
+
end
|
63
67
|
|
64
|
-
rule(:tree)
|
68
|
+
rule(:tree) do
|
65
69
|
((conditional_block | branch_block | expression) >> eol).repeat(0)
|
66
|
-
|
70
|
+
end
|
67
71
|
|
68
|
-
rule(:conditional_block)
|
72
|
+
rule(:conditional_block) do
|
69
73
|
(str('if') | str('unless')).as(:conditional) >>
|
70
74
|
spaces >> string.as(:conditional_clause) >> eol >>
|
71
75
|
tree.as(:true_tree) >>
|
72
76
|
(str('else') >> eol >> tree.as(:false_tree)).maybe >>
|
73
|
-
|
74
|
-
|
77
|
+
str('end')
|
78
|
+
end
|
75
79
|
|
76
|
-
rule(:branch_block)
|
80
|
+
rule(:branch_block) do
|
77
81
|
expression >> spaces >> str('do') >> eol >>
|
78
82
|
tree.as(:tree) >>
|
79
83
|
str('end')
|
80
|
-
|
84
|
+
end
|
81
85
|
|
82
|
-
rule(:metadata_entry)
|
86
|
+
rule(:metadata_entry) do
|
83
87
|
token.as(:key) >> str(':') >> spaces? >>
|
84
88
|
(string | float | integer | line).as(:value)
|
85
|
-
|
89
|
+
end
|
86
90
|
|
87
|
-
rule(:metadata)
|
91
|
+
rule(:metadata) do
|
88
92
|
str('---') >> eol >> (metadata_entry >> eol).repeat(0) >> str('---') >> eol
|
89
|
-
|
93
|
+
end
|
90
94
|
|
91
|
-
rule(:document)
|
95
|
+
rule(:document) do whitespace >> metadata.maybe.as(:metadata) >> branch_block.as(:tree) >> whitespace end
|
92
96
|
root(:document)
|
93
97
|
end
|
94
98
|
end
|
data/lib/swarm/pollen/reader.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "parser"
|
2
4
|
require_relative "transformer"
|
3
5
|
|
@@ -10,13 +12,13 @@ module Swarm
|
|
10
12
|
|
11
13
|
def to_hash
|
12
14
|
Transformer.new.apply(
|
13
|
-
Parser.new.parse(@pollen, :
|
15
|
+
Parser.new.parse(@pollen, reporter: Parslet::ErrorReporter::Deepest.new)
|
14
16
|
)
|
15
17
|
end
|
16
18
|
|
17
|
-
def to_json
|
19
|
+
def to_json(*_args)
|
18
20
|
to_hash.to_json
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
22
|
-
end
|
24
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "parslet"
|
2
4
|
|
3
5
|
module Swarm
|
@@ -13,51 +15,55 @@ module Swarm
|
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
|
-
rule(:
|
17
|
-
rule(:
|
18
|
-
rule(:
|
19
|
-
rule(:
|
20
|
-
rule(:
|
21
|
-
rule(:
|
18
|
+
rule(symbol: simple(:sym)) do sym.to_s end
|
19
|
+
rule(token: simple(:token)) do token.to_s end
|
20
|
+
rule(string: simple(:st)) do st.to_s end
|
21
|
+
rule(line: simple(:line)) do line.to_s end
|
22
|
+
rule(float: simple(:float)) do float.to_f end
|
23
|
+
rule(integer: simple(:int)) do int.to_i end
|
22
24
|
|
23
|
-
rule(:
|
25
|
+
rule(key: simple(:key), value: simple(:value)) do
|
24
26
|
{ key => value }
|
25
|
-
|
26
|
-
rule(:
|
27
|
+
end
|
28
|
+
rule(conditional: simple(:conditional), conditional_clause: simple(:clause), true_tree: subtree(:true_tree),
|
29
|
+
false_tree: subtree(:false_tree)) do
|
27
30
|
[conditional.to_s, { "condition" => clause }, {
|
28
31
|
"true" => [
|
29
32
|
["sequence", {}, true_tree]
|
30
33
|
],
|
31
34
|
"false" => [
|
32
35
|
["sequence", {}, false_tree]
|
33
|
-
]
|
36
|
+
]
|
34
37
|
}]
|
35
|
-
|
38
|
+
end
|
36
39
|
|
37
|
-
rule(:
|
40
|
+
rule(conditional: simple(:conditional), conditional_clause: simple(:clause), true_tree: subtree(:true_tree)) do
|
38
41
|
[conditional.to_s, { "condition" => clause }, {
|
39
42
|
"true" => [
|
40
43
|
["sequence", {}, true_tree]
|
41
44
|
]
|
42
45
|
}]
|
43
|
-
|
46
|
+
end
|
44
47
|
|
45
|
-
rule(:
|
48
|
+
rule(command: simple(:command)) do
|
46
49
|
[command.to_s, {}, []]
|
47
|
-
|
48
|
-
rule(:
|
50
|
+
end
|
51
|
+
rule(command: simple(:command), tree: subtree(:tree)) do
|
49
52
|
[command.to_s, {}, tree]
|
50
|
-
|
51
|
-
rule(:
|
53
|
+
end
|
54
|
+
rule(command: simple(:command), arguments: subtree(:args)) do |captures|
|
52
55
|
[captures[:command].to_s, transform_arguments(captures[:args]), []]
|
53
|
-
|
54
|
-
rule(:
|
56
|
+
end
|
57
|
+
rule(command: simple(:command), text_argument: simple(:ta), arguments: subtree(:args)) do |captures|
|
58
|
+
[captures[:command].to_s, { "text" => captures[:ta] }.merge(transform_arguments(captures[:args])), []]
|
59
|
+
end
|
60
|
+
rule(command: simple(:command), arguments: subtree(:args), tree: subtree(:tree)) do |captures|
|
55
61
|
[captures[:command].to_s, transform_arguments(captures[:args]), captures[:tree]]
|
56
|
-
|
57
|
-
rule(:
|
62
|
+
end
|
63
|
+
rule(command: simple(:command), text_argument: simple(:ta)) do
|
58
64
|
[command.to_s, { "text" => ta }, []]
|
59
|
-
|
60
|
-
rule(:
|
65
|
+
end
|
66
|
+
rule(metadata: subtree(:metadata), tree: subtree(:tree)) { |captures|
|
61
67
|
metadata = (captures[:metadata] || {}).reduce(:merge)
|
62
68
|
(metadata || {}).merge("definition" => captures[:tree])
|
63
69
|
}
|
data/lib/swarm/process.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "timeout"
|
2
4
|
|
3
5
|
module Swarm
|
4
6
|
class Process < HiveDweller
|
5
7
|
set_columns :process_definition_id, :workitem, :root_expression_id, :parent_expression_id
|
6
|
-
many_to_one :process_definition, :
|
7
|
-
many_to_one :parent_expression, :
|
8
|
-
many_to_one :root_expression, :
|
9
|
-
one_to_many :expressions, :
|
8
|
+
many_to_one :process_definition, class_name: "Swarm::ProcessDefinition"
|
9
|
+
many_to_one :parent_expression, class_name: "Swarm::Expression"
|
10
|
+
many_to_one :root_expression, class_name: "Swarm::Expression"
|
11
|
+
one_to_many :expressions, class_name: "Swarm::Expression"
|
10
12
|
|
11
13
|
def wait_until_finished(timeout: 5)
|
12
14
|
Swarm::Support.wait_until(timeout: timeout) { finished? }
|
@@ -19,11 +21,11 @@ module Swarm
|
|
19
21
|
|
20
22
|
def _launch
|
21
23
|
new_expression = SequenceExpression.create(
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
24
|
+
hive: hive,
|
25
|
+
parent_id: id,
|
26
|
+
position: [0],
|
27
|
+
workitem: workitem,
|
28
|
+
process_id: id
|
27
29
|
)
|
28
30
|
new_expression.apply
|
29
31
|
self.root_expression_id = new_expression.id
|
@@ -32,20 +34,25 @@ module Swarm
|
|
32
34
|
|
33
35
|
def finished?
|
34
36
|
reload!
|
35
|
-
root_expression
|
37
|
+
root_expression&.replied?
|
36
38
|
end
|
37
39
|
|
38
40
|
def node_at_position(position)
|
39
41
|
raise ArgumentError unless position == 0
|
42
|
+
|
40
43
|
process_definition.tree
|
41
44
|
end
|
42
45
|
|
43
46
|
def move_on_from(expression)
|
44
47
|
self.workitem = expression.workitem
|
45
48
|
save
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
return unless parent_expression
|
50
|
+
|
51
|
+
parent_expression.move_on_from(self)
|
52
|
+
end
|
53
|
+
|
54
|
+
def process_definition_name
|
55
|
+
process_definition.name
|
49
56
|
end
|
50
57
|
end
|
51
|
-
end
|
58
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "json"
|
2
4
|
|
3
5
|
module Swarm
|
@@ -5,11 +7,11 @@ module Swarm
|
|
5
7
|
class NotYetPersistedError < StandardError; end
|
6
8
|
|
7
9
|
set_columns :tree, :name, :version
|
8
|
-
one_to_many :processes, :
|
10
|
+
one_to_many :processes, class_name: "Swarm::Process"
|
9
11
|
|
10
12
|
class << self
|
11
13
|
def create_from_json(json, hive: Hive.default)
|
12
|
-
create(**parse_json_definition(json).merge(:
|
14
|
+
create(**parse_json_definition(json).merge(hive: hive))
|
13
15
|
end
|
14
16
|
|
15
17
|
def create_from_pollen(pollen, hive: Hive.default)
|
@@ -20,12 +22,12 @@ module Swarm
|
|
20
22
|
def parse_json_definition(json)
|
21
23
|
parsed = JSON.parse(json)
|
22
24
|
if parsed.is_a?(Array)
|
23
|
-
{ :
|
25
|
+
{ tree: parsed }
|
24
26
|
else
|
25
27
|
{
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
28
|
+
name: parsed["name"],
|
29
|
+
version: parsed["version"],
|
30
|
+
tree: parsed["definition"]
|
29
31
|
}
|
30
32
|
end
|
31
33
|
end
|
@@ -37,10 +39,11 @@ module Swarm
|
|
37
39
|
|
38
40
|
def create_process(workitem:, **args)
|
39
41
|
raise NotYetPersistedError unless id
|
42
|
+
|
40
43
|
Process.create(
|
41
|
-
args.merge({
|
42
|
-
:
|
43
|
-
:
|
44
|
+
**args.merge({
|
45
|
+
workitem: workitem,
|
46
|
+
process_definition_id: id
|
44
47
|
})
|
45
48
|
)
|
46
49
|
end
|
@@ -50,4 +53,4 @@ module Swarm
|
|
50
53
|
process.launch
|
51
54
|
end
|
52
55
|
end
|
53
|
-
end
|
56
|
+
end
|