swarm 0.2.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 +9 -5
- data/lib/swarm/expressions/activity_expression.rb +2 -0
- data/lib/swarm/expressions/branch_expression.rb +12 -15
- 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 +11 -18
- data/lib/swarm/hive_dweller.rb +79 -31
- 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 +25 -24
- data/lib/swarm/process_definition.rb +13 -9
- data/lib/swarm/router.rb +8 -6
- data/lib/swarm/storage/hash_storage.rb +10 -1
- data/lib/swarm/storage/key_value_storage.rb +40 -3
- data/lib/swarm/storage/redis_storage.rb +12 -1
- data/lib/swarm/storage.rb +3 -1
- data/lib/swarm/stored_workitem.rb +4 -2
- data/lib/swarm/support.rb +18 -13
- 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,38 +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
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
134
|
+
associations = hive.storage.load_associations(
|
135
|
+
association_name, owner: self, class_name: class_name || association_name, foreign_key: foreign_key
|
136
|
+
)
|
137
|
+
entities = associations.map { |association| self.class.reify_from_hash(association, hive: hive) }
|
138
|
+
instance_variable_set(:"@#{association_name}", entities)
|
127
139
|
end
|
128
140
|
end
|
129
|
-
|
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
|
+
}
|
149
|
+
end
|
150
|
+
|
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}")
|
154
|
+
memo || begin
|
155
|
+
key ||= :"#{association_name}_id"
|
156
|
+
associated_id = send(key)
|
157
|
+
return nil unless associated_id
|
158
|
+
|
159
|
+
klass = Swarm::Support.constantize((class_name || association_name).to_s)
|
160
|
+
instance_variable_set(:"@#{association_name}", klass.fetch(associated_id, hive: hive))
|
161
|
+
end
|
162
|
+
end
|
163
|
+
@associations[association_name] = {
|
164
|
+
type: :many_to_one, class_name: class_name || association_name, key: key
|
165
|
+
}
|
130
166
|
end
|
131
167
|
|
132
168
|
def create(hive: Hive.default, **args)
|
@@ -138,7 +174,7 @@ module Swarm
|
|
138
174
|
end
|
139
175
|
|
140
176
|
def storage_id_for_key(key)
|
141
|
-
if key.match(/^#{storage_type}
|
177
|
+
if key.match(/^#{storage_type}:/)
|
142
178
|
key
|
143
179
|
else
|
144
180
|
"#{storage_type}:#{key}"
|
@@ -154,25 +190,37 @@ module Swarm
|
|
154
190
|
|
155
191
|
def fetch(key, hive: Hive.default)
|
156
192
|
hsh = hive.storage[storage_id_for_key(key)].dup
|
157
|
-
|
193
|
+
reify_from_hash(hsh, hive: hive)
|
158
194
|
end
|
159
195
|
|
160
196
|
def ids(hive: Hive.default)
|
161
197
|
hive.storage.ids_for_type(storage_type)
|
162
198
|
end
|
163
199
|
|
164
|
-
def each(hive: Hive.default, subtypes: true
|
200
|
+
def each(hive: Hive.default, subtypes: true)
|
165
201
|
return to_enum(__method__, hive: hive, subtypes: subtypes) unless block_given?
|
202
|
+
|
166
203
|
ids(hive: hive).each do |id|
|
167
204
|
object = fetch(id, hive: hive)
|
168
|
-
if (subtypes && object.is_a?(self)) || object.
|
205
|
+
if (subtypes && object.is_a?(self)) || object.instance_of?(self)
|
169
206
|
yield object
|
170
207
|
end
|
171
208
|
end
|
172
209
|
end
|
173
210
|
|
174
211
|
def all(hive: Hive.default, subtypes: true)
|
175
|
-
|
212
|
+
hive.storage.all_of_type(storage_type, subtypes: subtypes).map { |hsh|
|
213
|
+
reify_from_hash(hsh.dup, hive: hive)
|
214
|
+
}
|
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
|
+
)
|
176
224
|
end
|
177
225
|
end
|
178
226
|
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,10 +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 :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"
|
8
12
|
|
9
13
|
def wait_until_finished(timeout: 5)
|
10
14
|
Swarm::Support.wait_until(timeout: timeout) { finished? }
|
@@ -16,42 +20,39 @@ module Swarm
|
|
16
20
|
end
|
17
21
|
|
18
22
|
def _launch
|
19
|
-
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
23
|
+
new_expression = SequenceExpression.create(
|
24
|
+
hive: hive,
|
25
|
+
parent_id: id,
|
26
|
+
position: [0],
|
27
|
+
workitem: workitem,
|
28
|
+
process_id: id
|
25
29
|
)
|
26
|
-
|
27
|
-
self.root_expression_id =
|
30
|
+
new_expression.apply
|
31
|
+
self.root_expression_id = new_expression.id
|
28
32
|
save
|
29
33
|
end
|
30
34
|
|
31
|
-
def root_expression
|
32
|
-
@root_expression ||= begin
|
33
|
-
reload! unless root_expression_id
|
34
|
-
if root_expression_id
|
35
|
-
Expression.fetch(root_expression_id, hive: hive)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
35
|
def finished?
|
41
|
-
|
36
|
+
reload!
|
37
|
+
root_expression&.replied?
|
42
38
|
end
|
43
39
|
|
44
40
|
def node_at_position(position)
|
45
41
|
raise ArgumentError unless position == 0
|
42
|
+
|
46
43
|
process_definition.tree
|
47
44
|
end
|
48
45
|
|
49
46
|
def move_on_from(expression)
|
50
47
|
self.workitem = expression.workitem
|
51
48
|
save
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
55
56
|
end
|
56
57
|
end
|
57
|
-
end
|
58
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "json"
|
2
4
|
|
3
5
|
module Swarm
|
@@ -5,10 +7,11 @@ module Swarm
|
|
5
7
|
class NotYetPersistedError < StandardError; end
|
6
8
|
|
7
9
|
set_columns :tree, :name, :version
|
10
|
+
one_to_many :processes, class_name: "Swarm::Process"
|
8
11
|
|
9
12
|
class << self
|
10
13
|
def create_from_json(json, hive: Hive.default)
|
11
|
-
create(**parse_json_definition(json).merge(:
|
14
|
+
create(**parse_json_definition(json).merge(hive: hive))
|
12
15
|
end
|
13
16
|
|
14
17
|
def create_from_pollen(pollen, hive: Hive.default)
|
@@ -19,12 +22,12 @@ module Swarm
|
|
19
22
|
def parse_json_definition(json)
|
20
23
|
parsed = JSON.parse(json)
|
21
24
|
if parsed.is_a?(Array)
|
22
|
-
{ :
|
25
|
+
{ tree: parsed }
|
23
26
|
else
|
24
27
|
{
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
+
name: parsed["name"],
|
29
|
+
version: parsed["version"],
|
30
|
+
tree: parsed["definition"]
|
28
31
|
}
|
29
32
|
end
|
30
33
|
end
|
@@ -36,10 +39,11 @@ module Swarm
|
|
36
39
|
|
37
40
|
def create_process(workitem:, **args)
|
38
41
|
raise NotYetPersistedError unless id
|
42
|
+
|
39
43
|
Process.create(
|
40
|
-
args.merge({
|
41
|
-
:
|
42
|
-
:
|
44
|
+
**args.merge({
|
45
|
+
workitem: workitem,
|
46
|
+
process_definition_id: id
|
43
47
|
})
|
44
48
|
)
|
45
49
|
end
|
@@ -49,4 +53,4 @@ module Swarm
|
|
49
53
|
process.launch
|
50
54
|
end
|
51
55
|
end
|
52
|
-
end
|
56
|
+
end
|