conflow 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b85fd52b7c1a2161135fc389c45b3f1e6754462a17ef30463435f1c919685950
4
- data.tar.gz: a5f05aa2c69b8426a72dc1070834ec74120a5053a74f93250098765c461105ef
3
+ metadata.gz: 572a2e10d542d2914de25fc748c1c153938e59b081aaef7829208395a86e462b
4
+ data.tar.gz: 99a32aa33c314eeabfa4feed3b386072ba2146139b552b257c59cd4b693fcca0
5
5
  SHA512:
6
- metadata.gz: 3291b765c557576651568d735b3bad21e7a191919a858e9365bbf7da97d632d09f99f3c7a2f35d3133b03d3e82a9802489dd1b63542bd1343325f89c74c22845
7
- data.tar.gz: a6797479cf68b310791680b2709ed54ebb9e372e26e87a1ffb2e685418a33eefa1b621bf5f68aa6ec05024c54d58f427123335ba204049a3fd7bfba4aa6d026e
6
+ metadata.gz: 8538390ead7bcc20bcea935aee1ec4d4ec7359eba95a89a8a5ddd14a3fbec25b69f9900d4548a4fd6370ae94eff13471ac794fe39a593d64a16ae0f2bf0abdf3
7
+ data.tar.gz: 53f5221e6bb9c0bd7dffdfdae3f0cb955f170e3aaa22a281a0e7f682952d9ad946de7daa93b0899935a5e77864f8178e5219e766182f74cbddfc16ea0d12881a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- conflow (0.2.0)
4
+ conflow (0.3.0)
5
5
  redis (~> 4.0)
6
6
 
7
7
  GEM
@@ -11,11 +11,11 @@ GEM
11
11
  coderay (1.1.2)
12
12
  connection_pool (2.2.1)
13
13
  diff-lcs (1.3)
14
- docile (1.1.5)
14
+ docile (1.3.0)
15
15
  json (2.1.0)
16
16
  method_source (0.9.0)
17
17
  parallel (1.12.1)
18
- parser (2.5.0.3)
18
+ parser (2.5.0.4)
19
19
  ast (~> 2.4.0)
20
20
  powerpack (0.1.1)
21
21
  pry (0.11.3)
@@ -45,8 +45,8 @@ GEM
45
45
  ruby-progressbar (~> 1.7)
46
46
  unicode-display_width (~> 1.0, >= 1.0.1)
47
47
  ruby-progressbar (1.9.0)
48
- simplecov (0.15.1)
49
- docile (~> 1.1.0)
48
+ simplecov (0.16.0)
49
+ docile (~> 1.1)
50
50
  json (>= 1.8, < 3)
51
51
  simplecov-html (~> 0.10.0)
52
52
  simplecov-html (0.10.2)
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Conflow
2
2
 
3
- [![Build Status](https://travis-ci.org/fanfilmu/conflow.svg?branch=master)](https://travis-ci.org/fanfilmu/conflow) [![Maintainability](https://api.codeclimate.com/v1/badges/80b66a285ca1803f391a/maintainability)](https://codeclimate.com/github/fanfilmu/conflow/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/80b66a285ca1803f391a/test_coverage)](https://codeclimate.com/github/fanfilmu/conflow/test_coverage)
3
+ [![Gem Version](https://badge.fury.io/rb/conflow.svg)](https://badge.fury.io/rb/conflow) [![Build Status](https://travis-ci.org/fanfilmu/conflow.svg?branch=master)](https://travis-ci.org/fanfilmu/conflow) [![Maintainability](https://api.codeclimate.com/v1/badges/80b66a285ca1803f391a/maintainability)](https://codeclimate.com/github/fanfilmu/conflow/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/80b66a285ca1803f391a/test_coverage)](https://codeclimate.com/github/fanfilmu/conflow/test_coverage)
4
4
 
5
- Conflow allows defining comlicated workflows with dependencies. Inspired by [Gush](https://github.com/chaps-io/gush) (the idea) and [Redis::Objects](https://github.com/nateware/redis-objects) (the implementation) it focuses solely on dependency logic, while leaving queueing jobs and executing them entirely in hands of the programmer.
5
+ Conflow allows defining complicated workflows with dependencies. Inspired by [Gush](https://github.com/chaps-io/gush) (the idea) and [Redis::Objects](https://github.com/nateware/redis-objects) (the implementation) it focuses solely on dependency logic, while leaving queueing jobs and executing them entirely in hands of the programmer.
6
6
 
7
7
  Please have a look at `Gush` if you already use Rails and ActiveJob - it might suit your needs better.
8
8
 
@@ -97,6 +97,24 @@ end
97
97
 
98
98
  ![Created graph](https://camo.githubusercontent.com/0b1ee59994323900906264ea50fbc9169e4d21dd/68747470733a2f2f63686172742e676f6f676c65617069732e636f6d2f63686172743f63686c3d646967726170682b472b2537422530442530412b2b72616e6b6469722533444c522533422530442530412b2b25323253544152542532322b2d2533452b25323246697273744a6f622532322530442530412b2b25323253544152542532322b2d2533452b253232496e646570656e64656e744a6f622532322530442530412b2b25323246697273744a6f622532322b2d2533452b2532325365636f6e644a6f622532322530442530412b2b253232496e646570656e64656e744a6f622532322b2d2533452b2532325365636f6e644a6f622532322530442530412b2b2532325365636f6e644a6f622532322b2d2533452b25323246696e69736855702532322530442530412b2b25323246696e69736855702532322b2d2533452b253232454e442532322530442530412537442530442530412b266368743d6776)
99
99
 
100
+ ### Hooks
101
+
102
+ If you want to modify your flow dynamically depending on results of your jobs, you can use hooks.
103
+
104
+ Hooks are methods defined on the `Flow` objects which will be called with result of the job (value returned by `Worker`, see [Performing jobs](https://github.com/fanfilmu/conflow#performing-jobs)).
105
+
106
+ ```ruby
107
+ class MyFlow < ApplicationFlow
108
+ def configure
109
+ run CollectEmails, hook: :send_notifications
110
+ end
111
+
112
+ def send_notifications(emails)
113
+ emails.each { |email| run SendNotification, params: { email: email } }
114
+ end
115
+ end
116
+ ```
117
+
100
118
  ### Performing jobs
101
119
 
102
120
  To perform job, use `Conflow::Worker` mixin. It adds `#perform` method, which accepts two arguments: IDs of the flow and the job.
@@ -127,6 +145,24 @@ SecondJob.new({}).call
127
145
  FinishUp.new({}).call
128
146
  ```
129
147
 
148
+ ## Theory
149
+
150
+ The main idea of the gem is, obviously, a directed graph containing information about dependencies. It is stored in Redis in following fields:
151
+
152
+ * `conflow:job:<id>:successors` - ([List](https://redis.io/topics/data-types#lists)) containing IDs of jobs which depend on `<id>`
153
+ * `conflow:flow:<id>:indegee` - ([Sorted Set](https://redis.io/topics/data-types#sorted-sets)) set of all unqueued jobs with score representing how many dependencies are not yet fulfilled
154
+
155
+ There are three main actions that can be performed on this graph (Redis-wise):
156
+
157
+ 1. Queue jobs
158
+ Removes all jobs with score 0 from `:indegree` set
159
+ 2. Complete job
160
+ Decrement scores of all of the job's successors by one
161
+ 3. Add job
162
+ Add job ID to `:successors` list for all jobs on which it depends and add job itself to `:indegree` set
163
+
164
+ All of these actions are performed via `eval`/`evalsha` - it lifts problems with synchronization (as scripts are executed as if in transaction) and significantly reduces amount of requests made to Redis.
165
+
130
166
  ## Development
131
167
 
132
168
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/lib/conflow.rb CHANGED
@@ -6,6 +6,7 @@ require "digest"
6
6
  require "json"
7
7
  require "redis"
8
8
 
9
+ require "conflow/redis"
9
10
  require "conflow/redis/connection_wrapper"
10
11
  require "conflow/redis/field"
11
12
  require "conflow/redis/value_field"
@@ -34,6 +35,12 @@ require "conflow/worker"
34
35
  # while leaving queueing jobs and executing them entirely in hands of the programmer.
35
36
  module Conflow
36
37
  class << self
38
+ # Assigns Redis connection to be used by {Conflow}. It will be wrapped in ConnectionWrapper
39
+ # for Redis instances, in order to have single API containing #with method.
40
+ # You can also assign ConnectionPool instance.
41
+ # @param conn [Redis, ConnectionPool] Redis connection
42
+ # @example
43
+ # Conflow.redis = Redis.new
37
44
  def redis=(conn)
38
45
  @redis =
39
46
  if defined?(ConnectionPool) && conn.is_a?(ConnectionPool)
@@ -43,6 +50,7 @@ module Conflow
43
50
  end
44
51
  end
45
52
 
53
+ # @return [Conflow::Redis::ConnectionWrapper, ConnectionPool] Wrapped Redis connection
46
54
  def redis
47
55
  self.redis = ::Redis.current unless defined?(@redis)
48
56
  @redis
@@ -15,13 +15,16 @@ module Conflow
15
15
  def run(job_class, params: {}, after: [], hook: nil)
16
16
  build_job(job_class, params, hook).tap do |job|
17
17
  job_classes[job_class] = job
18
- after = prepare_dependencies(after)
18
+ after = prepare_dependencies(after).compact
19
19
 
20
20
  call_script(Conflow::Redis::AddJobScript, job, after: after)
21
21
  queue_available_jobs
22
22
  end
23
23
  end
24
24
 
25
+ # Finishes job, changes its status, runs hook if it's present and queues new available jobs
26
+ # @param job [Conflow::Job] job to be marked as finished
27
+ # @param result [Object] result of the job to be passed to hook
25
28
  def finish(job, result = nil)
26
29
  send(job.hook.to_s, result) unless job.hook.nil?
27
30
  call_script(Conflow::Redis::CompleteJobScript, job)
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Conflow
4
+ # Redis module contains all logic related to handling flows in Redis
5
+ # @api private
6
+ module Redis
7
+ end
8
+ end
@@ -3,6 +3,7 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Adds new job to flow
6
+ # @api private
6
7
  class AddJobScript < Script
7
8
  # script accepts keys: flow.job_ids, flow.indegree, and keys successors of the jobs on which new job depends.
8
9
  # It also accepts one argument: id of the new job
@@ -3,55 +3,28 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Represents Redis list. It's methods mirror most used Array methods.
6
+ # @api private
6
7
  class ArrayField < Field
7
8
  include Enumerable
8
9
 
9
- def [](index)
10
- command :lindex, [key, index]
11
- end
12
-
13
- def []=(index, value)
14
- command :lset, [key, index, value]
15
- end
16
-
17
- def insert(value, after: nil, before: nil)
18
- if after
19
- command :linsert, [key, :after, after, value]
20
- elsif before
21
- command :linsert, [key, :before, before, value]
22
- else
23
- raise ArgumentError, "You need to pass one of [:after, :before] keywords"
24
- end
25
- end
26
-
10
+ # @return [Integer] number of elements in list
27
11
  def size
28
12
  command :llen, [key]
29
13
  end
30
14
 
15
+ # @return [Array] Ruby Array representation of Redis list
31
16
  def to_a
32
17
  command :lrange, [key, 0, -1]
33
18
  end; alias to_ary to_a
34
19
 
35
- def pop
36
- command :rpop, [key]
37
- end
38
-
20
+ # @param values [String...] one or more values to be added to the list
21
+ # @return [String] Redis response
39
22
  def push(*values)
40
23
  command :rpush, [key, values]
41
24
  end; alias << push
42
25
 
43
- def concat(ary)
44
- push(*ary)
45
- end
46
-
47
- def shift
48
- command :lpop, [key]
49
- end
50
-
51
- def unshift(value)
52
- command :lpush, [key, value]
53
- end
54
-
26
+ # Replace contents of Redis list
27
+ # @param new_array [Array] array of new values
55
28
  def overwrite(new_array)
56
29
  redis.with do |conn|
57
30
  conn.pipelined do
@@ -61,10 +34,14 @@ module Conflow
61
34
  end
62
35
  end
63
36
 
37
+ # Iterates over list
38
+ # @see to_a
64
39
  def each(&block)
65
40
  to_a.each(&block)
66
41
  end
67
42
 
43
+ # @param other [Object] Object to compare value with. Handles Arrays and other {ArrayField} objects
44
+ # @return [Boolean] true if equal
68
45
  def ==(other)
69
46
  case other
70
47
  when Array then to_a == other
@@ -73,6 +50,8 @@ module Conflow
73
50
  end
74
51
  end
75
52
 
53
+ # String representation of the list
54
+ # @see to_a
76
55
  def to_s
77
56
  to_a.to_s
78
57
  end
@@ -3,6 +3,7 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Adds new job to flow
6
+ # @api private
6
7
  class CompleteJobScript < Script
7
8
  self.script = <<~LUA
8
9
  local indegree_set = KEYS[1]
@@ -3,6 +3,7 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Wraps Redis connection to behave like connection pool
6
+ # @api private
6
7
  class ConnectionWrapper
7
8
  # @param redis [Redis] Redis connection to be wrapped
8
9
  def initialize(redis)
@@ -3,10 +3,13 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Base class for fields. All fields are assigned a Redis key.
6
+ # @api private
6
7
  class Field
8
+ # Redis key
7
9
  attr_reader :key
8
10
  alias id key
9
11
 
12
+ # @param key [String] Redis key to store the field in
10
13
  def initialize(key)
11
14
  @key = key
12
15
  end
@@ -3,9 +3,11 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Helper class for defining getter and setter methods for Fields
6
+ # @api private
6
7
  class FieldBuilder
7
8
  # This dynamic module contains accessor methods for a field
8
9
  class FieldAccessor < Module
10
+ # Creates new dynamic module with accessor methods for a field
9
11
  def initialize(field_name, klass, methods)
10
12
  super() do
11
13
  define_getter(field_name, klass) if methods.include?(:getter)
@@ -13,6 +15,7 @@ module Conflow
13
15
  end
14
16
  end
15
17
 
18
+ # Defines getter method, which will return proper {Conflow::Redis::Field}
16
19
  def define_getter(field_name, klass)
17
20
  instance_var = "@#{field_name}"
18
21
 
@@ -22,6 +25,7 @@ module Conflow
22
25
  end
23
26
  end
24
27
 
28
+ # Setter uses Field#overwrite method to replace contents of the field
25
29
  def define_setter(field_name)
26
30
  define_method("#{field_name}=") do |value|
27
31
  send(field_name).tap { |field| field.overwrite(value) }
@@ -29,13 +33,19 @@ module Conflow
29
33
  end
30
34
  end
31
35
 
32
- attr_reader :field_name, :klass
36
+ # Name of the accessor methods
37
+ attr_reader :field_name
38
+ # Class of the field. Should inherit from {Conflow::Redis::Field}
39
+ attr_reader :klass
33
40
 
41
+ # @see field_name
42
+ # @see klass
34
43
  def initialize(field_name, klass)
35
44
  @field_name = field_name
36
45
  @klass = klass
37
46
  end
38
47
 
48
+ # Creates dynamic {FieldAccessor} module and includes it in base class
39
49
  def call(base, methods: %i[getter setter])
40
50
  base.include(FieldAccessor.new(field_name, klass, methods))
41
51
  end
@@ -3,12 +3,15 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Findable module allows to use .find method on models with identifiers. It requires additional field: :type
6
+ # @api private
6
7
  module Findable
8
+ # Adds :type field to store class name of the Findable object
7
9
  def self.included(base)
8
10
  base.extend ClassMethods
9
11
  base.field :type, :value
10
12
  end
11
13
 
14
+ # Adds logic for assigning class name as type
12
15
  def initialize(*args)
13
16
  super
14
17
  self.type = self.class.name
@@ -16,6 +19,10 @@ module Conflow
16
19
 
17
20
  # Adds .find method which accepts ID and returns model of proper (sub)type
18
21
  module ClassMethods
22
+ # Creates new {Findable} object from ID.
23
+ # @example
24
+ # MyFlow.new.id #=> 13
25
+ # Conflow::Flow.find(13) #=> Myflow object
19
26
  def find(id)
20
27
  class_name = ValueField.new(format(key_template + ":type", id: id)).value
21
28
  raise ::Redis::CommandError, "#{name} with ID #{id} doesn't exist" unless class_name
@@ -3,26 +3,26 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Represents Redis hash. It's methods mirror most used Hash methods.
6
+ # @api private
6
7
  class HashField < Field
7
8
  include Enumerable
8
9
 
9
- def [](field)
10
- value = command(:hget, [key, field])
11
- value ? JSON.parse(value) : value
12
- end
13
-
14
- def []=(field, value)
15
- command :hset, [key, field, JSON.dump(value)]
16
- end
17
-
10
+ # Merges hashes, similar to Hash#merge
11
+ # @param hash [Hash] hash of keys and values to be merged
12
+ # @return [String] Redis response
13
+ #
14
+ # @example
15
+ # field.merge(smart: true, degree: :none)
18
16
  def merge(hash)
19
17
  command :hmset, [key, hash.flatten]
20
18
  end
21
19
 
22
- def delete(*fields)
23
- command :hdel, [key, fields]
24
- end
25
-
20
+ # Replaces currently stored hash with one given as param
21
+ # @param new_hash [Hash] hash of keys and values to be stored
22
+ # @return [String] Redis response
23
+ #
24
+ # @example
25
+ # field.overwrite(smart: true, degree: :none)
26
26
  def overwrite(new_hash)
27
27
  redis.with do |conn|
28
28
  conn.pipelined do
@@ -32,24 +32,26 @@ module Conflow
32
32
  end
33
33
  end
34
34
 
35
- def keys
36
- command(:hkeys, [key]).map(&:to_sym)
37
- end
38
-
39
- def size
40
- command :hlen, [key]
41
- end
42
-
35
+ # Creates Ruby Hash based on soted values. Keys will be symbolized and values JSON-parsed
36
+ # @return [String] Redis response
37
+ #
38
+ # @example
39
+ # field.to_h #=> { smart: true, degree: "none" }
43
40
  def to_h
44
41
  command(:hgetall, [key]).each_with_object({}) do |(key, value), hash|
45
42
  hash[key.to_sym] = JSON.parse(value)
46
43
  end
47
44
  end; alias to_hash to_h
48
45
 
46
+ # Iterates over hash.
47
+ # @see to_h
48
+ # @return [Enumerator] if no block given
49
49
  def each(&block)
50
50
  to_h.each(&block)
51
51
  end
52
52
 
53
+ # @param other [Object] Object to compare value with. Handles Hashes and other {HashField} objects
54
+ # @return [Boolean] true if equal
53
55
  def ==(other)
54
56
  case other
55
57
  when Hash then to_h == other
@@ -58,6 +60,7 @@ module Conflow
58
60
  end
59
61
  end
60
62
 
63
+ # @return [String] string representation of the hash
61
64
  def to_s
62
65
  to_h.to_s
63
66
  end
@@ -5,6 +5,7 @@ module Conflow
5
5
  # Identifier changes logic of fields so that they can be found by an id.
6
6
  # ID is a counter stored in redis under .counter_key
7
7
  # Key is build with template stored in .key_template
8
+ # @api private
8
9
  module Identifier
9
10
  # Extends base class with {ClassMethods}
10
11
  def self.included(base)
@@ -13,7 +14,10 @@ module Conflow
13
14
 
14
15
  # class methods for classes with identifier
15
16
  module ClassMethods
16
- attr_writer :counter_key, :key_template
17
+ # @see counter_key
18
+ attr_writer :counter_key
19
+ # @see key_template
20
+ attr_writer :key_template
17
21
 
18
22
  # Copies *counter_key* and *key_template* to child classes
19
23
  def inherited(base)
@@ -3,6 +3,7 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Models adds .field method which allows to define fields easily.
6
+ # @api private
6
7
  module Model
7
8
  # Extends base class with .field and .has_many methods
8
9
  def self.included(base)
@@ -3,6 +3,7 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Removes jobs from indegree set, adds them to queued list, and returns IDs of queued jobs.
6
+ # @api private
6
7
  class QueueJobsScript < Script
7
8
  self.script = <<~LUA
8
9
  local indegree_set = KEYS[1]
@@ -3,6 +3,7 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Main class for scripts, handling logic of executing and caching scripts.
6
+ # @api private
6
7
  class Script
7
8
  class << self
8
9
  # @return [Boolean] whether scripts are cached or not
@@ -3,6 +3,7 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Represents Redis list. It's methods mirror most used Set methods.
6
+ # @api private
6
7
  class SetField < Field
7
8
  include Enumerable
8
9
 
@@ -4,6 +4,7 @@ module Conflow
4
4
  module Redis
5
5
  # Represents Redis sorted set. Closest Ruby representation is a Hash
6
6
  # where keys are elements of the set and values represent score.
7
+ # @api private
7
8
  class SortedSetField < Field
8
9
  # Adds one or more keys to the set.
9
10
  # @param hash [Hash] hash of values and scores to be added
@@ -25,17 +26,6 @@ module Conflow
25
26
  command :zscore, [key, value]
26
27
  end
27
28
 
28
- # Set score of given element.
29
- # @param value [String, Symbol] element of the set
30
- # @param rank [Numeric] score to be assigned
31
- # @return [Integer] Number of added elements (1 if key didn't exist, 0 otherwise)
32
- #
33
- # @example
34
- # field[:last] = 24 #=> 0
35
- def []=(value, rank)
36
- command :zadd, [key, rank, value]
37
- end
38
-
39
29
  # Number of elements in the set
40
30
  # @return [Integer] Size of the set
41
31
  #
@@ -55,22 +45,6 @@ module Conflow
55
45
  command :zrem, [key, value]
56
46
  end
57
47
 
58
- # Returns first *n* elements of the sorted set
59
- # @param num [Integer] amount of elements to be returned. Defaults to 1.
60
- # @return [String, Array<String>] first *num* elements from the set
61
- def first(num = 1)
62
- result = command :zrange, [key, 0, num - 1]
63
- num == 1 ? result[0] : result
64
- end
65
-
66
- # Returns last *n* elements of the sorted set
67
- # @param num [Integer] amount of elements to be returned. Defaults to 1.
68
- # @return [String, Array<String>] last *num* elements from the set
69
- def last(num = 1)
70
- result = command :zrevrange, [key, 0, num - 1]
71
- num == 1 ? result[0] : result
72
- end
73
-
74
48
  # Creates regular Ruby Hash based on Redis values.
75
49
  # @return [Hash] Hash representing this Sorted set
76
50
  def to_h
@@ -3,6 +3,7 @@
3
3
  module Conflow
4
4
  module Redis
5
5
  # Represents single value (Redis String). Values are serialized as JSON in order to preserve type.
6
+ # @api private
6
7
  class ValueField < Field
7
8
  # @note *value* must be serializable through JSON.dump
8
9
  # @param value [Object] new value to be saved
@@ -20,7 +21,7 @@ module Conflow
20
21
 
21
22
  # @param other [Object] Object to compare value with. Handles Strings, Numerics,
22
23
  # Symbols and other {ValueField} objects
23
- # @return [String] Redis response
24
+ # @return [Boolean] true if equal
24
25
  def ==(other)
25
26
  case other
26
27
  when String, Numeric then value == other
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Conflow
4
4
  # Current version of the gem
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.0"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michał Begejowicz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-11 00:00:00.000000000 Z
11
+ date: 2018-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -148,6 +148,7 @@ files:
148
148
  - lib/conflow/flow.rb
149
149
  - lib/conflow/flow/job_handler.rb
150
150
  - lib/conflow/job.rb
151
+ - lib/conflow/redis.rb
151
152
  - lib/conflow/redis/add_job_script.rb
152
153
  - lib/conflow/redis/array_field.rb
153
154
  - lib/conflow/redis/complete_job_script.rb