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
data/lib/swarm/router.rb CHANGED
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Swarm
2
4
  class Router
3
5
  class << self
4
6
  def expression_class_for_node(node)
5
7
  command = node[0]
6
8
  expression_type = case command
7
- when "if", "unless"
8
- "conditional"
9
- when "sequence", "concurrence", "subprocess"
10
- command
11
- else
12
- "activity"
9
+ when "if", "unless"
10
+ "conditional"
11
+ when "sequence", "concurrence", "subprocess"
12
+ command
13
+ else
14
+ "activity"
13
15
  end
14
16
  Swarm::Support.constantize("swarm/#{expression_type}_expression")
15
17
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "key_value_storage"
2
4
 
3
5
  module Swarm
@@ -8,6 +10,13 @@ module Swarm
8
10
  keys.map { |key| key.gsub(regex_for_type(type), '\1') }
9
11
  end
10
12
 
13
+ def all_of_type(type, subtypes: true)
14
+ store.select { |key, value|
15
+ key.match(regex_for_type(type)) &&
16
+ (subtypes || value["type"] == type)
17
+ }.values
18
+ end
19
+
11
20
  def delete(key)
12
21
  store.delete(key)
13
22
  end
@@ -17,4 +26,4 @@ module Swarm
17
26
  end
18
27
  end
19
28
  end
20
- end
29
+ end
@@ -1,27 +1,64 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Swarm
2
4
  module Storage
3
5
  class KeyValueStorage
6
+ class AssociationKeyMissingError < StandardError; end
7
+
4
8
  attr_reader :store
5
9
 
6
10
  def initialize(store)
7
11
  @store = store
8
12
  end
9
13
 
14
+ def trace
15
+ self["trace"]
16
+ end
17
+
18
+ def trace=(traced)
19
+ self["trace"] = traced
20
+ end
21
+
10
22
  def regex_for_type(type)
11
- /^#{type}\:(.*)/
23
+ /^#{type}:(.*)/
24
+ end
25
+
26
+ def ids_for_type(_type)
27
+ raise "Not implemented yet!"
12
28
  end
13
29
 
14
- def ids_for_type(type)
30
+ def all_of_type(_type)
15
31
  raise "Not implemented yet!"
16
32
  end
17
33
 
34
+ def add_association(association_name, associated, owner:, class_name:, foreign_key: nil)
35
+ key = :"#{association_name}_ids"
36
+ raise AssociationKeyMissingError, key unless owner.respond_to?(key)
37
+
38
+ ids = owner.send(key) || owner.send("#{key}=", [])
39
+ ids << associated.id
40
+ associated
41
+ end
42
+
43
+ def load_associations(association_name, owner:, class_name:, foreign_key: nil)
44
+ key = :"#{association_name}_ids"
45
+ raise AssociationKeyMissingError, key unless owner.respond_to?(key)
46
+
47
+ ids = owner.send(key) || []
48
+ ids.map { |id|
49
+ self["#{class_name.split("::").last}:#{id}"]
50
+ }.compact
51
+ end
52
+
18
53
  def serialize(value)
19
54
  return nil if value.nil?
55
+
20
56
  value.to_json
21
57
  end
22
58
 
23
59
  def deserialize(value)
24
60
  return nil if value.nil?
61
+
25
62
  JSON.parse(value)
26
63
  end
27
64
 
@@ -33,7 +70,7 @@ module Swarm
33
70
  store[key] = serialize(value)
34
71
  end
35
72
 
36
- def delete(key)
73
+ def delete(_key)
37
74
  raise "Not implemented yet!"
38
75
  end
39
76
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "redis"
2
4
  require_relative "key_value_storage"
3
5
 
@@ -8,6 +10,15 @@ module Swarm
8
10
  store.keys("#{type}:*").map { |key| key.gsub(regex_for_type(type), '\1') }
9
11
  end
10
12
 
13
+ def all_of_type(type, subtypes: true)
14
+ hsh = store.mapped_mget(*store.keys("#{type}:*"))
15
+ if subtypes
16
+ hsh.values
17
+ else
18
+ hsh.select { |_key, value| value["type"] == type }.values
19
+ end
20
+ end
21
+
11
22
  def delete(key)
12
23
  store.del(key)
13
24
  end
@@ -17,4 +28,4 @@ module Swarm
17
28
  end
18
29
  end
19
30
  end
20
- end
31
+ end
data/lib/swarm/storage.rb CHANGED
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "storage/hash_storage"
2
4
  require_relative "storage/redis_storage"
3
5
 
4
6
  module Swarm
5
7
  module Storage
6
8
  end
7
- end
9
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Swarm
2
4
  class StoredWorkitem < HiveDweller
3
5
  extend Forwardable
@@ -5,11 +7,11 @@ module Swarm
5
7
  def_delegators :expression, :node, :command, :arguments, :process_id, :workitem
6
8
 
7
9
  set_columns :expression_id
8
- many_to_one :expression, :class_name => "Swarm::Expression"
10
+ many_to_one :expression, class_name: "Swarm::Expression"
9
11
 
10
12
  def proceed
11
13
  delete
12
14
  expression.reply
13
15
  end
14
16
  end
15
- end
17
+ end
data/lib/swarm/support.rb CHANGED
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "securerandom"
2
4
 
3
5
  module Swarm
4
6
  module Support
5
7
  class << self
6
8
  def deep_merge(hsh1, hsh2, combine_arrays: :override)
7
- hsh1.merge(hsh2) { |key, v1, v2|
9
+ hsh1.merge(hsh2) { |_key, v1, v2|
8
10
  if [v1, v2].all? { |v| v.is_a?(Array) }
9
11
  combine_arrays(v1, v2, method: combine_arrays)
10
12
  elsif [v1, v2].all? { |v| v.is_a?(Hash) }
@@ -43,9 +45,20 @@ module Swarm
43
45
  "#{Time.now.strftime("%Y%m%d-%H%M%S")}-#{SecureRandom.uuid}"
44
46
  end
45
47
 
48
+ def tokenize(string)
49
+ return nil if string.nil?
50
+
51
+ string.to_s.gsub(/&/, ' and ').
52
+ gsub(%r{[ /]+}, '_').
53
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
54
+ downcase
55
+ end
56
+
46
57
  def camelize(string)
47
- string = string.sub(/^[a-z\d]*/) { $&.capitalize }
48
- string = string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
58
+ string = string.sub(/^[a-z\d]*/) { ::Regexp.last_match(0).capitalize }
59
+ string.gsub(%r{(?:_|(/))([a-z\d]*)}) {
60
+ "#{::Regexp.last_match(1)}#{::Regexp.last_match(2).capitalize}"
61
+ }.gsub('/', '::')
49
62
  end
50
63
 
51
64
  def constantize(string)
@@ -62,20 +75,12 @@ module Swarm
62
75
  constant
63
76
  end
64
77
 
65
- def slice(hash, *keys)
66
- {}.tap { |h|
67
- keys.each { |k|
68
- h[k] = hash[k] if hash.has_key?(k)
69
- }
70
- }
71
- end
72
-
73
78
  def wait_until(timeout: 5, initial_delay: nil)
74
79
  sleep(initial_delay) if initial_delay.is_a?(Numeric)
75
- Timeout::timeout(timeout) do
80
+ Timeout.timeout(timeout) do
76
81
  sleep 0.05 until yield
77
82
  end
78
83
  end
79
84
  end
80
85
  end
81
- end
86
+ end
data/lib/swarm/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Swarm
2
- VERSION = "0.2.0"
4
+ VERSION = "0.4.0"
3
5
  end
data/lib/swarm.rb CHANGED
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
1
4
  require "swarm/version"
2
5
  require "swarm/support"
3
- require "swarm/engine/base/queue"
6
+ require "swarm/engine/queue"
4
7
  require "swarm/engine/volatile/queue"
5
8
  require "swarm/engine/worker"
6
9
  require "swarm/hive"
@@ -19,7 +22,6 @@ require "swarm/participants/storage_participant"
19
22
  require "swarm/pollen/reader"
20
23
  require "swarm/storage"
21
24
 
22
-
23
25
  module Swarm
24
26
  # Your code goes here...
25
27
  end
data/swarm.gemspec CHANGED
@@ -21,11 +21,13 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_dependency "redis"
23
23
  spec.add_dependency "parslet"
24
+ spec.add_dependency "dentaku"
24
25
 
25
- spec.add_development_dependency "bundler", "~> 1.8"
26
- spec.add_development_dependency "rake", "~> 10.0"
27
- spec.add_development_dependency "rspec", "~> 3.0"
28
- spec.add_development_dependency "timecop", "~> 0.7"
29
- spec.add_development_dependency 'simplecov'
26
+ spec.add_development_dependency "bundler"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "rspec", "~> 3"
29
+ spec.add_development_dependency "timecop"
30
+ spec.add_development_dependency "simplecov"
30
31
  spec.add_development_dependency "pry"
32
+ spec.add_development_dependency "rubocop"
31
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swarm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ravi Gadad
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-02-17 00:00:00.000000000 Z
11
+ date: 2025-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -38,62 +38,76 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dentaku
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - "~>"
59
+ - - ">="
46
60
  - !ruby/object:Gem::Version
47
- version: '1.8'
61
+ version: '0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - "~>"
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
- version: '1.8'
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - "~>"
73
+ - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: '10.0'
75
+ version: '0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - "~>"
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
- version: '10.0'
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '3.0'
89
+ version: '3'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '3.0'
96
+ version: '3'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: timecop
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - "~>"
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
- version: '0.7'
103
+ version: '0'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - "~>"
108
+ - - ">="
95
109
  - !ruby/object:Gem::Version
96
- version: '0.7'
110
+ version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: simplecov
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +136,20 @@ dependencies:
122
136
  - - ">="
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
125
153
  description: A Ruby workflow engine
126
154
  email:
127
155
  - ravi@gadad.net
@@ -140,14 +168,13 @@ files:
140
168
  - bin/console
141
169
  - bin/setup
142
170
  - lib/swarm.rb
143
- - lib/swarm/engine/base/job.rb
144
- - lib/swarm/engine/base/queue.rb
171
+ - lib/swarm/engine/job.rb
172
+ - lib/swarm/engine/queue.rb
145
173
  - lib/swarm/engine/volatile/job.rb
146
174
  - lib/swarm/engine/volatile/queue.rb
147
175
  - lib/swarm/engine/worker.rb
148
176
  - lib/swarm/engine/worker/command.rb
149
177
  - lib/swarm/evaluation/expression_evaluator.rb
150
- - lib/swarm/evaluation/workitem_context.rb
151
178
  - lib/swarm/expression.rb
152
179
  - lib/swarm/expressions/activity_expression.rb
153
180
  - lib/swarm/expressions/branch_expression.rb
@@ -158,6 +185,7 @@ files:
158
185
  - lib/swarm/hive.rb
159
186
  - lib/swarm/hive_dweller.rb
160
187
  - lib/swarm/observers/base.rb
188
+ - lib/swarm/observers/logger.rb
161
189
  - lib/swarm/participant.rb
162
190
  - lib/swarm/participants/storage_participant.rb
163
191
  - lib/swarm/participants/trace_participant.rb
@@ -179,7 +207,7 @@ homepage: https://github.com/bumbleworks/swarm
179
207
  licenses:
180
208
  - MIT
181
209
  metadata: {}
182
- post_install_message:
210
+ post_install_message:
183
211
  rdoc_options: []
184
212
  require_paths:
185
213
  - lib
@@ -194,9 +222,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
222
  - !ruby/object:Gem::Version
195
223
  version: '0'
196
224
  requirements: []
197
- rubyforge_project:
198
- rubygems_version: 2.2.5
199
- signing_key:
225
+ rubygems_version: 3.5.11
226
+ signing_key:
200
227
  specification_version: 4
201
228
  summary: A Ruby workflow engine
202
229
  test_files: []
@@ -1,17 +0,0 @@
1
- module Swarm
2
- class WorkitemContext
3
- attr_reader :workitem
4
-
5
- def initialize(workitem)
6
- @workitem = Support.symbolize_keys(workitem)
7
- end
8
-
9
- def method_missing(method, *args)
10
- if workitem.has_key?(method)
11
- workitem.fetch(method, nil)
12
- else
13
- super
14
- end
15
- end
16
- end
17
- end