simpler_workflow 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OTY0NTU1MjRiNzlkNjc1MmYxN2EyMDY4NjBhZTVkNWQyOTE2NTBjMg==
5
+ data.tar.gz: !binary |-
6
+ MDNhMWI1MWUwMDI3NGIxMWUxMjlkMzEzZDAzYTc4OWM3ZmE1NjZhNQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NjJhY2M4ZDkxYmNlZmIzYzk5OGNiYjMyZDNjYmFiMGY3MmFjMzBiMWUyNTBh
10
+ MWNhMjU3ODQwMjQ3NDNiNTA3NWJiOWI1MzFhMzhhZDg1YjdkYmZhNzU5MTll
11
+ Nzg5NWJlNWVjMTNiZDE4MzYwYmI2N2E4ZTVlYzA3YTM2MzdjMjY=
12
+ data.tar.gz: !binary |-
13
+ ZjdkNmMwYjk3OGE4ZTJiYWM2Mjc3OGU5MzRiZjdjZGMzMTIxOTU5MTkxNDlm
14
+ ZmRjZGQ3ZTFhNGE3NmE3N2YwYTZlNGFkYzQ0NzhjZWM0NTRjMzBiMDRkMDk3
15
+ NTU0NGEzM2QwMTkyZTdkMWY1NTYyOTk2NWI0ZWZiOWRmODVkMjQ=
data/README.md CHANGED
@@ -198,7 +198,77 @@ Here are a few recommendations on when to change the version of a workflow or ac
198
198
  2. You may want to bump a version if you have work in progress under an existing workflow and you need to introduce changes for new work. You will need to keep the older activity and or workflow around while it completes.
199
199
  3. You do not need to bump the version when you change the work performed by the activity or the decision loop itself. This is code that is directly managed by SimplerWorkflow and isn't communicated to AWS. This only works if you do not want previous workflows to finish using the previous version of the code though.
200
200
 
201
- ## Running Workflows
201
+ ## Running Workflows as Daemons
202
+
203
+ Often you'll need to expose several SWF components and make sure they run at all time on a server as daemons. For this, you may use `ParentProcess` in companion with a demonizer like the daemons gem. In the parent process, you define what children it must monitor and how many versions of each children must run.
204
+
205
+ Here's a sample use of parent process.
206
+
207
+ ```ruby
208
+ class SimpleWorkflowAPI
209
+
210
+ extend SimplerWorkflow::ParentProcess
211
+
212
+ log_level Logger::DEBUG
213
+
214
+ workers 4
215
+
216
+ domain = SimplerWorkflow::Domain.domains "my_ops"
217
+
218
+ # define your activities
219
+ test_activity = domain.register_activity :test, "1.0.0" do
220
+ perform_activity do |task|
221
+ task.complete! :result => "approved"
222
+ end
223
+ end
224
+
225
+ # let the parent process start the loop
226
+ # this boot will be run as many times as workers you indicate
227
+ # e.g. here you'll have 4 instances of the test_activity running in parallel.
228
+ on_boot do
229
+ test_activity.start_activity_loop
230
+ # more activities initializations go here
231
+ end
232
+ end
233
+ ```
234
+
235
+ This is only the class starting the processes, if you need to daemonize this an expose as a unix service, for example in `/etc/init.d/simpler_workflow`, you can create a daemon script and link it to the services folder and then configure it to start on boot.
236
+
237
+ Assuming the last example is called `boot.rb` this can be a sample `daemon.rb`:
238
+
239
+ ```ruby
240
+ #!/usr/bin/env/ ruby
241
+ require 'rubygems'
242
+ require 'bundler/setup' #load all gems in your Gemfile
243
+ require 'daemons' # require the daemons gem
244
+
245
+ dirmode = :normal
246
+ # Check if we're in a deployment machine
247
+ # to store logs in /var/run or in the app folder
248
+ if ENV['ENV']
249
+ log_dir = "/var/log/swf"
250
+ pid_dir = "/var/run/swf"
251
+ else
252
+ log_dir = File.expand_path '../log/', __FILE__
253
+ pid_dir = File.expand_path '../log/pid', __FILE__
254
+ end
255
+ script_path = File.expand_path '../boot.rb', __FILE__
256
+ Daemons.run script_path, {
257
+ :app_name => "my_daemon",
258
+ :dir_mode => dirmode,
259
+ :log_dir => log_dir,
260
+ :dir => pid_dir,
261
+ :multiple => false,
262
+ :monitor => true,
263
+ :log_output => true,
264
+ # backtrace causes errors detecting as uncatched
265
+ # some correctly handled exceptions. Keep disabled.
266
+ :backtrace => false
267
+ }
268
+ ```
269
+
270
+ For more details on daemons you can look in http://daemons.rubyforge.org/Daemons.html
271
+ You can still use any other daemonization script, or even handle it yourself as taught in http://www.jstorimer.com/products/working-with-unix-processes
202
272
 
203
273
  There is a new Rake task called ```simpler_workflow:work``` that will
204
274
  look for workflows located under the ```lib/workflow``` directory. This
@@ -57,4 +57,5 @@ module SimplerWorkflow
57
57
  autoload :ActivityRegistry, 'simpler_workflow/activity_registry'
58
58
  autoload :OptionsAsMethods, 'simpler_workflow/options_as_methods'
59
59
  autoload :DefaultExceptionReporter, 'simpler_workflow/default_exception_reporter'
60
+ autoload :ParentProcess, 'simpler_workflow/parent_process'
60
61
  end
@@ -97,12 +97,18 @@ module SimplerWorkflow
97
97
  $0 = "Activity: #{name} #{version}"
98
98
 
99
99
  Signal.trap('QUIT') do
100
- logger.info("Received SIGQUIT")
101
- @time_to_exit = true
100
+ # Don't log in trap, ruby 2 complains
101
+ # since we need to exit quickly, only delay quit
102
+ # if we are in the middle of a task
103
+ if @in_task
104
+ @time_to_exit = true
105
+ else
106
+ Process.exit 0
107
+ end
102
108
  end
103
109
 
104
110
  Signal.trap('INT') do
105
- logger.info("Received SIGINT")
111
+ # Don't log in trap, ruby 2 complains
106
112
  Process.exit!(0)
107
113
  end
108
114
 
@@ -117,6 +123,7 @@ module SimplerWorkflow
117
123
  domain.activity_tasks.poll(task_list) do |task|
118
124
  begin
119
125
  logger.info("Received task...")
126
+ @in_task = true
120
127
  perform_task(task)
121
128
  unless task.responded?
122
129
  task.complete!
@@ -128,6 +135,8 @@ module SimplerWorkflow
128
135
  context[:activity_id] = task.activity_id
129
136
  SimplerWorkflow.exception_reporter.report(e, context)
130
137
  task.fail! :reason => e.message, :details => { :failure_policy => :fail }.to_json unless task.responded?
138
+ ensure
139
+ @in_task = false
131
140
  end
132
141
  end
133
142
  Process.exit(0) if @time_to_exit
@@ -0,0 +1,81 @@
1
+ module SimplerWorkflow
2
+
3
+ module ParentProcess
4
+
5
+ # This class is aimed to be used with daemons gem or something similar
6
+ # it launches as many workers as required, which is just running the on boot time block n times
7
+ # a sample daemon using daemons gem would like this:
8
+
9
+ # #!/usr/bin/env/ ruby
10
+ # require 'rubygems'
11
+ # require 'bundler/setup'
12
+ # require 'daemons'
13
+ # dirmode = :normal
14
+ # # Check if we're in a deployment machine
15
+ # # to store logs in /var/run or in the app folder
16
+ # if ENV['ENV']
17
+ # log_dir = "/var/log/swf"
18
+ # pid_dir = "/var/run/swf"
19
+ # else
20
+ # log_dir = File.expand_path '../log/', __FILE__
21
+ # pid_dir = File.expand_path '../log/pid', __FILE__
22
+ # end
23
+ # script_path = File.expand_path '../boot.rb', __FILE__
24
+ # Daemons.run script_path, {
25
+ # :app_name => "my_daemon",
26
+ # :dir_mode => dirmode,
27
+ # :log_dir => log_dir,
28
+ # :dir => pid_dir,
29
+ # :multiple => false,
30
+ # :monitor => true,
31
+ # :log_output => true,
32
+ # # backtrace causes errors detecting as uncatched
33
+ # # some correctly handled exceptions. Keep disabled.
34
+ # :backtrace => false
35
+ # }
36
+
37
+
38
+ require 'fileutils'
39
+
40
+ def self.extended(base)
41
+
42
+ $logger = Logger.new STDOUT
43
+
44
+ base.extend ClassMethods
45
+
46
+ Signal.trap('TERM') { base.graceful_exit 'QUIT'}
47
+
48
+ Signal.trap('INT') { base.graceful_exit 'INT'}
49
+
50
+ end
51
+
52
+ module ClassMethods
53
+
54
+ def graceful_exit(s)
55
+ SimplerWorkflow.child_processes.each do |child|
56
+ Process.kill(s, child)
57
+ end
58
+ end
59
+
60
+ def workers(val)
61
+ @workers = val
62
+ end
63
+
64
+ def log_level(val)
65
+ @log_level = val
66
+ end
67
+
68
+ def on_boot(&block)
69
+ $logger.level = @log_level if @log_level
70
+ # separate this execution in the log
71
+ $logger.info "Booting with #{@workers} workers----------------------------"
72
+ @workers.times { yield }
73
+ # we wait for all children processes to exit; when QUIT is sent
74
+ # we terminate them and this will automatically exit.
75
+ Process.waitall
76
+
77
+ end
78
+
79
+ end
80
+ end
81
+ end
@@ -1,3 +1,3 @@
1
1
  module SimplerWorkflow
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -31,12 +31,18 @@ module SimplerWorkflow
31
31
  $0 = "Workflow: #{name} #{version}"
32
32
 
33
33
  Signal.trap('QUIT') do
34
- logger.info("Received SIGQUIT")
35
- @time_to_exit = true
34
+ # Don't log in trap, ruby 2 complains
35
+ # since we need to exit quickly, only delay quit
36
+ # if we are in the middle of a task
37
+ if @in_task
38
+ @time_to_exit = true
39
+ else
40
+ Process.exit 0
41
+ end
36
42
  end
37
43
 
38
44
  Signal.trap('INT') do
39
- logger.info("Received SIGINT")
45
+ # Don't log in trap, ruby 2 complains
40
46
  Process.exit!(0)
41
47
  end
42
48
 
@@ -48,6 +54,7 @@ module SimplerWorkflow
48
54
  begin
49
55
  logger.info("Waiting for a decision task for #{name.to_s}, #{version} listening to #{task_list}")
50
56
  domain.decision_tasks.poll_for_single_task(task_list) do |decision_task|
57
+ @in_task = true # lock for TERM signal handling
51
58
  handle_decision_task(decision_task)
52
59
  end
53
60
  Process.exit 0 if @time_to_exit
@@ -63,6 +70,8 @@ module SimplerWorkflow
63
70
  }
64
71
  SimplerWorkflow.exception_reporter.report(e, context)
65
72
  raise e
73
+ ensure
74
+ @in_task = false
66
75
  end
67
76
  end
68
77
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simpler_workflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
5
- prerelease:
4
+ version: 0.3.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Frederic Jean
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-07-26 00:00:00.000000000 Z
11
+ date: 2013-11-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: aws-sdk
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: map
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: map
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rake
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ! '>='
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ! '>='
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rspec
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ! '>='
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ! '>='
92
81
  - !ruby/object:Gem::Version
@@ -94,7 +83,6 @@ dependencies:
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: travis-lint
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - ! '>='
100
88
  - !ruby/object:Gem::Version
@@ -102,7 +90,6 @@ dependencies:
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - ! '>='
108
95
  - !ruby/object:Gem::Version
@@ -110,7 +97,6 @@ dependencies:
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: pry
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
101
  - - ! '>='
116
102
  - !ruby/object:Gem::Version
@@ -118,7 +104,6 @@ dependencies:
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
108
  - - ! '>='
124
109
  - !ruby/object:Gem::Version
@@ -126,7 +111,6 @@ dependencies:
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: pry-nav
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
115
  - - ! '>='
132
116
  - !ruby/object:Gem::Version
@@ -134,7 +118,6 @@ dependencies:
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
122
  - - ! '>='
140
123
  - !ruby/object:Gem::Version
@@ -142,7 +125,6 @@ dependencies:
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: logging
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
129
  - - ! '>='
148
130
  - !ruby/object:Gem::Version
@@ -150,7 +132,6 @@ dependencies:
150
132
  type: :development
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
136
  - - ! '>='
156
137
  - !ruby/object:Gem::Version
@@ -180,6 +161,7 @@ files:
180
161
  - lib/simpler_workflow/default_exception_reporter.rb
181
162
  - lib/simpler_workflow/domain.rb
182
163
  - lib/simpler_workflow/options_as_methods.rb
164
+ - lib/simpler_workflow/parent_process.rb
183
165
  - lib/simpler_workflow/tasks.rb
184
166
  - lib/simpler_workflow/version.rb
185
167
  - lib/simpler_workflow/workflow.rb
@@ -192,7 +174,8 @@ files:
192
174
  - spec/workflow_spec.rb
193
175
  homepage: https://github.com/fredjean/simpler_workflow
194
176
  licenses: []
195
- post_install_message: ! "simpler_workflow 0.3.1\n========================\n\nHave
177
+ metadata: {}
178
+ post_install_message: ! "simpler_workflow 0.3.2\n========================\n\nHave
196
179
  a look at https://github.com/fredjean/simpler_workflow/wiki/MIgrating-to-0.2.0 if
197
180
  you\nare upgrading from a 0.1.x version of the gem. There is a fundamental change
198
181
  in how the \nactivity and decision loops are run. You may need to adjust your application
@@ -202,25 +185,20 @@ rdoc_options: []
202
185
  require_paths:
203
186
  - lib
204
187
  required_ruby_version: !ruby/object:Gem::Requirement
205
- none: false
206
188
  requirements:
207
189
  - - ! '>='
208
190
  - !ruby/object:Gem::Version
209
191
  version: 1.9.0
210
192
  required_rubygems_version: !ruby/object:Gem::Requirement
211
- none: false
212
193
  requirements:
213
194
  - - ! '>='
214
195
  - !ruby/object:Gem::Version
215
196
  version: '0'
216
- segments:
217
- - 0
218
- hash: -904765461876988747
219
197
  requirements: []
220
198
  rubyforge_project:
221
- rubygems_version: 1.8.23
199
+ rubygems_version: 2.1.1
222
200
  signing_key:
223
- specification_version: 3
201
+ specification_version: 4
224
202
  summary: A wrapper and DSL around Amazon's Simple Workflow Service with the goal of
225
203
  making it almost pleasant to define workflows.
226
204
  test_files: