rockflow 1.0.1 → 1.1.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
  SHA1:
3
- metadata.gz: 819099699ced7464dab4ee7da34befdfaabb7105
4
- data.tar.gz: d25ff7b3b6ecf716189c66f6f75f9d3bd89f5702
3
+ metadata.gz: 546f63965d1789bdc29172964e3125bc7eac9612
4
+ data.tar.gz: 220b01079dd75f593fdbcc28752973c6dcfadb35
5
5
  SHA512:
6
- metadata.gz: 2547a34beced3dcb0d6eeca1c3a9982f43ed8bed799fa4b6ca7857e5154ed35a2f3501504a8cf49d56d101fdffd90137dcf023976e07db61e3aec00a2e27cae4
7
- data.tar.gz: 3d83e5122f6adb07ad979ebbac1f3df04bf9d247f234cf7b44b564689c5292874c0fa84df3a01b7da020b45d127fb8c6fd5102ad5c8b5d9b183913bf53f70b73
6
+ metadata.gz: 444410dd4f41b0047b8e6cc9cec9195c3655f2f9b2b518567fb9cd70300ffba039f99d68003e35912309a272ab85384007ca1475e0888e3f331b0c67f12e4432
7
+ data.tar.gz: 0668671711e72e3f9273182e508713b8909d31c15ce647ae707085c8c089fdade49bc8bd2cb1aed7eedf54c4156f5d23dd3f71566794a65c859375d747370d18
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Rockflow
2
+ [![Gem Version](https://badge.fury.io/rb/rockflow.svg)](http://badge.fury.io/rb/rockflow)
2
3
 
3
4
  What is rockflow? Well with rockflow you are able to define workflows (yes even parallel workflows) by writing simple small steps and aggregating them in your flow (the bigger picture... you know)
4
5
 
@@ -29,7 +30,7 @@ To write your own flow you need two ingredients: the **flow** and your **steps**
29
30
  # app/workflows/awesome_flow.rb
30
31
  class AwesomeFlow < Rockflow::Flow
31
32
  def setup
32
- rock RockStep1
33
+ rock RockStep1, conditions: [{pre: -> { payload[:foo].present? }}]
33
34
  rock RockStep2, params: {lorem: 'ipsum'}
34
35
  rock RockStep3, after: [RockStep1, RockStep2]
35
36
  end
@@ -82,6 +83,24 @@ flow.concert! # execute all steps
82
83
  Define your flow by inheriting from **RockFlow::Flow**. Inside your defined flow override the setup method and use the **rock** keyword defined by your step class. Available options for the rock method are at the moment:
83
84
  - **after** which takes a StepClass or an array of step classes.
84
85
  - **params** you can specify extra params to be used in a step.
86
+ - **conditions** are used to define pre or post conditions for every step.
87
+
88
+ #### Conditions
89
+ Conditions are used to define pre or post conditions for every step. To finish a step each given pre or post condition must evaluate to true.
90
+ Let me give you an example:
91
+ ```ruby
92
+ class MyFlow < Rockflow::Flow
93
+
94
+ def setup
95
+ rock Step1, conditions: [{pre: -> { false }},
96
+ {post: -> { true }}]
97
+ end
98
+
99
+ end
100
+
101
+ flow = MyFlow.new
102
+ flow.concert # => returns false because the pre condition is false
103
+ ```
85
104
 
86
105
  After that start writing your steps by inheriting from **RockFlow::Step** and overriding the **it_up** method. Inside of your inherited class you can use following methods.
87
106
 
@@ -0,0 +1,6 @@
1
+ module Rockflow
2
+ module Errors
3
+ class PostCondition < StandardError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Rockflow
2
+ module Errors
3
+ class PreCondition < StandardError
4
+ end
5
+ end
6
+ end
data/lib/rockflow/flow.rb CHANGED
@@ -16,15 +16,16 @@ module Rockflow
16
16
  @steps << klazz.new(self, opts)
17
17
  end
18
18
 
19
- def concert!
20
- while !steps_finished?
21
- ::Parallel.each(next_free_steps, in_threads: 4) do |step|
22
- step.it_up
23
- step.finish!
24
- end
19
+ def concert
20
+ execute_steps.inject(true) do |result, elem|
21
+ result && !elem.errors.any?
25
22
  end
26
23
  end
27
24
 
25
+ def concert!
26
+ execute_steps
27
+ end
28
+
28
29
  def next_free_steps
29
30
  @steps.select do |step|
30
31
  step.after_dependencies_finished? && !step.finished?
@@ -33,10 +34,22 @@ module Rockflow
33
34
 
34
35
  def steps_finished?
35
36
  @steps.inject(true) do |result, elem|
36
- result = result && elem.finished?
37
+ result = result && (elem.finished? || elem.failed?)
37
38
  result
38
39
  end
39
40
  end
40
41
 
42
+ def execute_steps
43
+ while !steps_finished?
44
+ ::Parallel.each(next_free_steps, in_threads: 4) do |step|
45
+ step.execute_pre_conditions
46
+ step.it_up
47
+ step.execute_post_conditions
48
+ step.finish! unless step.failed?
49
+ end
50
+ end
51
+ @steps
52
+ end
53
+
41
54
  end
42
55
  end
data/lib/rockflow/step.rb CHANGED
@@ -1,12 +1,14 @@
1
1
  module Rockflow
2
2
  class Step
3
- attr_accessor :flow, :status, :params
3
+ attr_accessor :flow, :status, :params, :conditions, :errors
4
4
 
5
5
  def initialize(flow, opts = {})
6
6
  @flow = flow
7
7
  @after_dependencies = []
8
+ @errors = []
8
9
  @params = opts[:params]
9
10
  @status = :not_started
11
+ @conditions = opts[:conditions]
10
12
  add_after_dependencies(opts[:after])
11
13
  end
12
14
 
@@ -25,6 +27,14 @@ module Rockflow
25
27
  @status == :finished
26
28
  end
27
29
 
30
+ def fail!
31
+ @status = :failed
32
+ end
33
+
34
+ def failed?
35
+ @status == :failed
36
+ end
37
+
28
38
  def add_payload(key, value)
29
39
  @flow.payload[key] = value
30
40
  end
@@ -45,5 +55,58 @@ module Rockflow
45
55
  end
46
56
  end
47
57
 
58
+ def select_conditions(pre_or_post)
59
+ conditions.select do |cond|
60
+ cond[pre_or_post.to_sym]
61
+ end.map do |cond|
62
+ cond[pre_or_post.to_sym]
63
+ end
64
+ end
65
+
66
+ def execute_pre_conditions
67
+ select_conditions(:pre).each do |cond|
68
+ exec_condition(cond, ::Rockflow::Errors::PreCondition)
69
+ end
70
+ end
71
+
72
+ def execute_post_conditions
73
+ select_conditions(:post).each do |cond|
74
+ exec_condition(cond, ::Rockflow::Errors::PostCondition)
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def exec_condition(block_or_symbol, error)
81
+ exec_block_or_symbol(block_or_symbol, error) do
82
+ exec_condition_block(block_or_symbol, error)
83
+ end
84
+ end
85
+
86
+ def exec_block_or_symbol(block_or_symbol, error)
87
+ if block_or_symbol.is_a? Proc
88
+ yield
89
+ elsif block_or_symbol.is_a? Symbol
90
+ exec_method(block_or_symbol, error)
91
+ end
92
+ end
93
+
94
+ def exec_condition_block(block, error)
95
+ unless block.call
96
+ fail_execution(error)
97
+ end
98
+ end
99
+
100
+ def exec_method(method, error)
101
+ unless self.step.send(method.to_sym)
102
+ fail_execution(error)
103
+ end
104
+ end
105
+
106
+ def fail_execution(error)
107
+ self.fail!
108
+ @errors << error.new(self)
109
+ end
110
+
48
111
  end
49
112
  end
@@ -1,3 +1,3 @@
1
1
  module Rockflow
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/rockflow.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'rockflow/version'
2
2
  require 'rockflow/flow'
3
3
  require 'rockflow/step'
4
+ require 'rockflow/errors/post_condition'
5
+ require 'rockflow/errors/pre_condition'
4
6
  require 'parallel'
5
7
  module Rockflow
6
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rockflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erwin Schens
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-08-24 00:00:00.000000000 Z
11
+ date: 2015-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parallel
@@ -87,6 +87,8 @@ files:
87
87
  - bin/console
88
88
  - bin/setup
89
89
  - lib/rockflow.rb
90
+ - lib/rockflow/errors/post_condition.rb
91
+ - lib/rockflow/errors/pre_condition.rb
90
92
  - lib/rockflow/flow.rb
91
93
  - lib/rockflow/step.rb
92
94
  - lib/rockflow/version.rb
@@ -111,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
113
  version: '0'
112
114
  requirements: []
113
115
  rubyforge_project:
114
- rubygems_version: 2.4.6
116
+ rubygems_version: 2.4.8
115
117
  signing_key:
116
118
  specification_version: 4
117
119
  summary: Create workflows the easy way