swarm 0.1.0 → 0.2.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 +4 -4
- data/README.md +14 -12
- data/lib/swarm.rb +2 -1
- data/lib/swarm/hive.rb +5 -3
- data/lib/swarm/hive_dweller.rb +12 -3
- data/lib/swarm/process_definition.rb +0 -1
- data/lib/swarm/storage.rb +4 -53
- data/lib/swarm/storage/hash_storage.rb +20 -0
- data/lib/swarm/storage/key_value_storage.rb +45 -0
- data/lib/swarm/storage/redis_storage.rb +20 -0
- data/lib/swarm/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c08aee506af8648cba7e34c9bf1a0f6771da43fb
|
4
|
+
data.tar.gz: fa7e78cf7ccb4c0f134623f8001a8782af141164
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57e8b887897b7b94f34f0ddec8e90a5ef6024ba9e03deeb03ddb05ca7d802a1e438fcf1b657b750a38020112f7dcfb2fd41ea1b5f9dfbcde4bdc20b00bc0a6e4
|
7
|
+
data.tar.gz: 3cea3598a30320cc93a15d41e827714980b2c2f82bec4e4fe196f7989470be9560662ca6a09f9513ebb67715c83e38b305bf63192c4307084518f9502150c44a
|
data/README.md
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
# Swarm
|
2
2
|
|
3
|
-
|
3
|
+
[](https://badge.fury.io/rb/swarm)
|
4
4
|
|
5
|
-
|
5
|
+
Swarm is a (very much still work-in-progress) workflow engine for Ruby, combining a process definition DSL, a set of built-in expressions, a worker framework to actually run process instances, and a storage mechanism to persist instances and deferred expressions.
|
6
|
+
|
7
|
+
Currently it requires Redis as a backend to persist state (though for testing you can use transient in-process memory storage). The goal is to extract the storage so other backends can be swapped in as the process state repository.
|
8
|
+
|
9
|
+
For performing the work itself, Swarm only comes with an in-process memory storage, which means jobs queued up at the time of stopping the worker will be lost. For a non-volatile worker, you'll want to use [swarm-beanstalk](http://github.com/bumbleworks/swarm-beanstalk), which uses [beanstalkd](http://kr.github.io/beanstalkd/) (via [beaneater](https://github.com/beanstalkd/beaneater)).
|
6
10
|
|
7
11
|
## Installation
|
8
12
|
|
@@ -22,18 +26,16 @@ Or install it yourself as:
|
|
22
26
|
|
23
27
|
## Usage
|
24
28
|
|
25
|
-
|
26
|
-
|
27
|
-
## Development
|
29
|
+
Instructions coming soon!
|
28
30
|
|
29
|
-
|
31
|
+
## Acknowledgements
|
30
32
|
|
31
|
-
|
33
|
+
Huge thanks to @jmettraux, author of (now discontinued) [ruote](https://github.com/jmettraux/ruote), for getting me excited about workflow engines, and for inspiring this fun and educational project of mine.
|
32
34
|
|
33
35
|
## Contributing
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/swarm-beanstalk. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
38
|
+
|
39
|
+
## License
|
40
|
+
|
41
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/lib/swarm.rb
CHANGED
@@ -17,7 +17,8 @@ require "swarm/stored_workitem"
|
|
17
17
|
require "swarm/participants/trace_participant"
|
18
18
|
require "swarm/participants/storage_participant"
|
19
19
|
require "swarm/pollen/reader"
|
20
|
-
require "
|
20
|
+
require "swarm/storage"
|
21
|
+
|
21
22
|
|
22
23
|
module Swarm
|
23
24
|
# Your code goes here...
|
data/lib/swarm/hive.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative "storage"
|
2
|
-
|
3
1
|
module Swarm
|
4
2
|
class Hive
|
5
3
|
class MissingTypeError < StandardError; end
|
@@ -34,7 +32,11 @@ module Swarm
|
|
34
32
|
end
|
35
33
|
|
36
34
|
def inspect
|
37
|
-
"#<Swarm::Hive storage: #{
|
35
|
+
"#<Swarm::Hive storage: #{storage_class}, work_queue: #{work_queue.name}>"
|
36
|
+
end
|
37
|
+
|
38
|
+
def storage_class
|
39
|
+
storage.class.name.split('::').last
|
38
40
|
end
|
39
41
|
|
40
42
|
def traced
|
data/lib/swarm/hive_dweller.rb
CHANGED
@@ -55,7 +55,8 @@ module Swarm
|
|
55
55
|
def save
|
56
56
|
if new? || changed?
|
57
57
|
@id ||= Swarm::Support.uuid_with_timestamp
|
58
|
-
storage[storage_id] = to_hash
|
58
|
+
storage[storage_id] = to_hash.merge(:updated_at => Time.now)
|
59
|
+
reload!
|
59
60
|
end
|
60
61
|
self
|
61
62
|
end
|
@@ -95,14 +96,22 @@ module Swarm
|
|
95
96
|
super
|
96
97
|
subclass.instance_variable_set(:@columns, [])
|
97
98
|
subclass.instance_variable_set(:@associations, [])
|
99
|
+
subclass.set_columns :updated_at, :created_at
|
98
100
|
end
|
99
101
|
|
100
102
|
def set_columns(*args)
|
101
|
-
attr_reader *args
|
102
103
|
args.each do |arg|
|
103
104
|
define_method("#{arg}=") { |value|
|
104
105
|
change_attribute(arg, value)
|
105
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
|
+
}
|
106
115
|
end
|
107
116
|
@columns = @columns | args
|
108
117
|
end
|
@@ -121,7 +130,7 @@ module Swarm
|
|
121
130
|
end
|
122
131
|
|
123
132
|
def create(hive: Hive.default, **args)
|
124
|
-
new(hive: hive, **args).save
|
133
|
+
new(hive: hive, created_at: Time.now, **args).save
|
125
134
|
end
|
126
135
|
|
127
136
|
def storage_type
|
data/lib/swarm/storage.rb
CHANGED
@@ -1,56 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
attr_reader :backend
|
4
|
-
|
5
|
-
def initialize(backend)
|
6
|
-
@backend = backend
|
7
|
-
end
|
8
|
-
|
9
|
-
def regex_for_type(type)
|
10
|
-
/^#{type}\:(.*)/
|
11
|
-
end
|
12
|
-
|
13
|
-
def ids_for_type(type)
|
14
|
-
keys = if backend.is_a?(Redis)
|
15
|
-
backend.keys("#{type}:*")
|
16
|
-
else
|
17
|
-
backend.keys.select { |key| key.match(regex_for_type(type)) }
|
18
|
-
end
|
19
|
-
keys.map { |key| key.gsub(regex_for_type(type), '\1') }
|
20
|
-
end
|
21
|
-
|
22
|
-
def serialize(value)
|
23
|
-
return nil if value.nil?
|
24
|
-
value.to_json
|
25
|
-
end
|
1
|
+
require_relative "storage/hash_storage"
|
2
|
+
require_relative "storage/redis_storage"
|
26
3
|
|
27
|
-
|
28
|
-
|
29
|
-
JSON.parse(value)
|
30
|
-
end
|
31
|
-
|
32
|
-
def [](key)
|
33
|
-
deserialize(backend[key])
|
34
|
-
end
|
35
|
-
|
36
|
-
def []=(key, value)
|
37
|
-
backend[key] = serialize(value)
|
38
|
-
end
|
39
|
-
|
40
|
-
def delete(key)
|
41
|
-
if backend.respond_to?(:del)
|
42
|
-
backend.del(key)
|
43
|
-
else
|
44
|
-
backend.delete(key)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def truncate
|
49
|
-
if backend.respond_to?(:flushdb)
|
50
|
-
backend.flushdb
|
51
|
-
else
|
52
|
-
backend.clear
|
53
|
-
end
|
54
|
-
end
|
4
|
+
module Swarm
|
5
|
+
module Storage
|
55
6
|
end
|
56
7
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative "key_value_storage"
|
2
|
+
|
3
|
+
module Swarm
|
4
|
+
module Storage
|
5
|
+
class HashStorage < KeyValueStorage
|
6
|
+
def ids_for_type(type)
|
7
|
+
keys = store.keys.select { |key| key.match(regex_for_type(type)) }
|
8
|
+
keys.map { |key| key.gsub(regex_for_type(type), '\1') }
|
9
|
+
end
|
10
|
+
|
11
|
+
def delete(key)
|
12
|
+
store.delete(key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def truncate
|
16
|
+
store.clear
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Swarm
|
2
|
+
module Storage
|
3
|
+
class KeyValueStorage
|
4
|
+
attr_reader :store
|
5
|
+
|
6
|
+
def initialize(store)
|
7
|
+
@store = store
|
8
|
+
end
|
9
|
+
|
10
|
+
def regex_for_type(type)
|
11
|
+
/^#{type}\:(.*)/
|
12
|
+
end
|
13
|
+
|
14
|
+
def ids_for_type(type)
|
15
|
+
raise "Not implemented yet!"
|
16
|
+
end
|
17
|
+
|
18
|
+
def serialize(value)
|
19
|
+
return nil if value.nil?
|
20
|
+
value.to_json
|
21
|
+
end
|
22
|
+
|
23
|
+
def deserialize(value)
|
24
|
+
return nil if value.nil?
|
25
|
+
JSON.parse(value)
|
26
|
+
end
|
27
|
+
|
28
|
+
def [](key)
|
29
|
+
deserialize(store[key])
|
30
|
+
end
|
31
|
+
|
32
|
+
def []=(key, value)
|
33
|
+
store[key] = serialize(value)
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete(key)
|
37
|
+
raise "Not implemented yet!"
|
38
|
+
end
|
39
|
+
|
40
|
+
def truncate
|
41
|
+
raise "Not implemented yet!"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "redis"
|
2
|
+
require_relative "key_value_storage"
|
3
|
+
|
4
|
+
module Swarm
|
5
|
+
module Storage
|
6
|
+
class RedisStorage < KeyValueStorage
|
7
|
+
def ids_for_type(type)
|
8
|
+
store.keys("#{type}:*").map { |key| key.gsub(regex_for_type(type), '\1') }
|
9
|
+
end
|
10
|
+
|
11
|
+
def delete(key)
|
12
|
+
store.del(key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def truncate
|
16
|
+
store.flushdb
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/swarm/version.rb
CHANGED
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ravi Gadad
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -168,6 +168,9 @@ files:
|
|
168
168
|
- lib/swarm/process_definition.rb
|
169
169
|
- lib/swarm/router.rb
|
170
170
|
- lib/swarm/storage.rb
|
171
|
+
- lib/swarm/storage/hash_storage.rb
|
172
|
+
- lib/swarm/storage/key_value_storage.rb
|
173
|
+
- lib/swarm/storage/redis_storage.rb
|
171
174
|
- lib/swarm/stored_workitem.rb
|
172
175
|
- lib/swarm/support.rb
|
173
176
|
- lib/swarm/version.rb
|