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.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -1
  3. data/Gemfile +2 -0
  4. data/Rakefile +3 -1
  5. data/bin/console +1 -0
  6. data/lib/swarm/engine/{base/job.rb → job.rb} +2 -0
  7. data/lib/swarm/engine/{base/queue.rb → queue.rb} +7 -5
  8. data/lib/swarm/engine/volatile/job.rb +6 -2
  9. data/lib/swarm/engine/volatile/queue.rb +7 -4
  10. data/lib/swarm/engine/worker/command.rb +5 -1
  11. data/lib/swarm/engine/worker.rb +22 -19
  12. data/lib/swarm/evaluation/expression_evaluator.rb +21 -14
  13. data/lib/swarm/expression.rb +9 -5
  14. data/lib/swarm/expressions/activity_expression.rb +2 -0
  15. data/lib/swarm/expressions/branch_expression.rb +12 -15
  16. data/lib/swarm/expressions/concurrence_expression.rb +8 -5
  17. data/lib/swarm/expressions/conditional_expression.rb +4 -2
  18. data/lib/swarm/expressions/sequence_expression.rb +4 -2
  19. data/lib/swarm/expressions/subprocess_expression.rb +4 -1
  20. data/lib/swarm/hive.rb +11 -18
  21. data/lib/swarm/hive_dweller.rb +79 -31
  22. data/lib/swarm/observers/base.rb +3 -1
  23. data/lib/swarm/observers/logger.rb +40 -0
  24. data/lib/swarm/participant.rb +3 -1
  25. data/lib/swarm/participants/storage_participant.rb +6 -4
  26. data/lib/swarm/participants/trace_participant.rb +2 -0
  27. data/lib/swarm/pollen/parser.rb +48 -44
  28. data/lib/swarm/pollen/reader.rb +5 -3
  29. data/lib/swarm/pollen/transformer.rb +30 -24
  30. data/lib/swarm/process.rb +25 -24
  31. data/lib/swarm/process_definition.rb +13 -9
  32. data/lib/swarm/router.rb +8 -6
  33. data/lib/swarm/storage/hash_storage.rb +10 -1
  34. data/lib/swarm/storage/key_value_storage.rb +40 -3
  35. data/lib/swarm/storage/redis_storage.rb +12 -1
  36. data/lib/swarm/storage.rb +3 -1
  37. data/lib/swarm/stored_workitem.rb +4 -2
  38. data/lib/swarm/support.rb +18 -13
  39. data/lib/swarm/version.rb +3 -1
  40. data/lib/swarm.rb +4 -2
  41. data/swarm.gemspec +7 -5
  42. metadata +51 -24
  43. data/lib/swarm/evaluation/workitem_context.rb +0 -17
@@ -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(:updated_at => Time.now)
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
- :id => id,
73
- :type => self.class.name
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.each do |type|
84
- instance_variable_set(:"@#{type}", nil)
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
- define_method("#{arg}=") { |value|
105
- change_attribute(arg, value)
106
- }
107
-
108
- define_method(arg) {
109
- val = instance_variable_get(:"@#{arg}")
110
- if /_at$/.match(arg) && val.is_a?(String)
111
- val = Time.parse(val)
112
- end
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 many_to_one(type, class_name: nil)
120
- define_method(type) do
121
- memo = instance_variable_get(:"@#{type}")
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
- key = self.send(:"#{type}_id")
124
- return nil unless key
125
- klass = Swarm::Support.constantize("#{class_name || type}")
126
- instance_variable_set(:"@#{type}", klass.fetch(key, :hive => hive))
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
- @associations << type
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
- hive.reify_from_hash(hsh)
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, &block)
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.class == self
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
- to_a(hive: hive, subtypes: subtypes)
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Swarm
2
4
  module Observers
3
5
  class Base
@@ -14,4 +16,4 @@ module Swarm
14
16
  def after_action; end
15
17
  end
16
18
  end
17
- end
19
+ end
@@ -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
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Swarm
2
4
  class Participant
3
5
  attr_reader :hive, :expression
4
6
 
5
- def initialize(hive: Hive.default, expression:)
7
+ def initialize(expression:, hive: Hive.default)
6
8
  @hive = hive
7
9
  @expression = expression
8
10
  end
@@ -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
- :hive => hive,
8
- :expression_id => expression.id
9
- })
8
+ StoredWorkitem.create(
9
+ hive: hive,
10
+ expression_id: expression.id
11
+ )
10
12
  end
11
13
  end
12
14
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "../participant"
2
4
 
3
5
  module Swarm
@@ -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) { (optionally_spaced(match['\n'])).repeat(1) }
11
- rule(:whitespace) { match('\s').repeat(0) }
12
- rule(:spaces) { match[' \t'].repeat(1) }
13
- rule(:spaces?) { spaces.maybe }
14
- rule(:comma) { optionally_spaced(str(',')) }
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 { |s,c| str(c.captures[:q]) }.absent? >> any
32
- ).repeat.as(:string) >> dynamic { |s,c| str(c.captures[:q]) }
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) { str(':') >> token.as(:symbol) }
40
- rule(:token) { (match('[a-z_]') >> match('[a-zA-Z0-9_]').repeat(0)).as(: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) { rocket_pair | colon_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) | string.as(:text_argument)
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(if unless else end).map { |w| str(w) }.reduce(:|)
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
- str('end')
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) { whitespace >> metadata.maybe.as(:metadata) >> branch_block.as(:tree) >> whitespace }
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
@@ -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, :reporter => Parslet::ErrorReporter::Deepest.new)
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(:symbol => simple(:sym)) { sym.to_s }
17
- rule(:token => simple(:token)) { token.to_s }
18
- rule(:string => simple(:st)) { st.to_s }
19
- rule(:line => simple(:line)) { line.to_s }
20
- rule(:float => simple(:float)) { float.to_f }
21
- rule(:integer => simple(:int)) { int.to_i }
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(:key => simple(:key), :value => simple(:value)) {
25
+ rule(key: simple(:key), value: simple(:value)) do
24
26
  { key => value }
25
- }
26
- rule(:conditional => simple(:conditional), :conditional_clause => simple(:clause), :true_tree => subtree(:true_tree), :false_tree => subtree(:false_tree)) {
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(:conditional => simple(:conditional), :conditional_clause => simple(:clause), :true_tree => subtree(:true_tree)) {
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(:command => simple(:command)) {
48
+ rule(command: simple(:command)) do
46
49
  [command.to_s, {}, []]
47
- }
48
- rule(:command => simple(:command), :tree => subtree(:tree)) {
50
+ end
51
+ rule(command: simple(:command), tree: subtree(:tree)) do
49
52
  [command.to_s, {}, tree]
50
- }
51
- rule(:command => simple(:command), :arguments => subtree(:args)) { |captures|
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(:command => simple(:command), :arguments => subtree(:args), :tree => subtree(:tree)) { |captures|
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(:command => simple(:command), :text_argument => simple(:ta)) {
62
+ end
63
+ rule(command: simple(:command), text_argument: simple(:ta)) do
58
64
  [command.to_s, { "text" => ta }, []]
59
- }
60
- rule(:metadata => subtree(:metadata), :tree => subtree(:tree)) { |captures|
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, :class_name => "Swarm::ProcessDefinition"
7
- many_to_one :parent_expression, :class_name => "Swarm::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
- root_expression = SequenceExpression.create(
20
- :hive => hive,
21
- :parent_id => id,
22
- :position => [0],
23
- :workitem => workitem,
24
- :process_id => id
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
- root_expression.apply
27
- self.root_expression_id = 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
- root_expression && root_expression.replied?
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
- if parent_expression
53
- parent_expression.move_on_from(self)
54
- end
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(:hive => hive))
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
- { :tree => parsed }
25
+ { tree: parsed }
23
26
  else
24
27
  {
25
- :name => parsed["name"],
26
- :version => parsed["version"],
27
- :tree => parsed["definition"]
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
- :workitem => workitem,
42
- :process_definition_id => id
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