simpler_workflow 0.1.7 → 0.1.8
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.
- data/bin/swf +144 -0
- data/lib/aws/simple_workflow/decision_task_additions.rb +10 -1
- data/lib/simpler_workflow/activity.rb +2 -8
- data/lib/simpler_workflow/options_as_methods.rb +11 -0
- data/lib/simpler_workflow/version.rb +1 -1
- data/lib/simpler_workflow/workflow.rb +6 -9
- data/lib/simpler_workflow.rb +9 -2
- metadata +28 -26
data/bin/swf
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# setup
|
5
|
+
#
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
script = File.expand_path(__FILE__).gsub(%r|\breleases/\d+\b|, 'current')
|
9
|
+
script_dir = File.dirname(script)
|
10
|
+
rails_root = File.dirname(script_dir)
|
11
|
+
|
12
|
+
Dir.chdir(rails_root)
|
13
|
+
|
14
|
+
require File.join(rails_root, 'config', 'env.rb')
|
15
|
+
|
16
|
+
FileUtils.mkdir_p(File.join(rails_root, 'log', 'jobs'))
|
17
|
+
FileUtils.touch(File.join(rails_root, 'log', 'jobs', 'pid'))
|
18
|
+
|
19
|
+
%w(
|
20
|
+
BACKGROUND PIDFILE QUEUE VVERBOSE INTERVAL COUNT
|
21
|
+
).each{|key| ENV.delete(key)}
|
22
|
+
|
23
|
+
quiet = ARGV.delete('-q') || ARGV.delete('--quiet')
|
24
|
+
mode = ARGV.shift || 'run'
|
25
|
+
|
26
|
+
pidfile = './log/jobs/pid'
|
27
|
+
pid = Integer(IO.read(pidfile).strip) rescue nil
|
28
|
+
running = begin; Process.kill(0, pid); true; rescue Object; false; end
|
29
|
+
|
30
|
+
# go
|
31
|
+
#
|
32
|
+
case mode
|
33
|
+
when 'pid'
|
34
|
+
puts(pid) if running
|
35
|
+
|
36
|
+
when 'run'
|
37
|
+
exit(42) unless DATA.flock(File::LOCK_EX | File::LOCK_NB)
|
38
|
+
|
39
|
+
ENV['PIDFILE'] = pidfile
|
40
|
+
ENV['QUEUE'] = 'jobs'
|
41
|
+
ENV['VVERBOSE'] = '1'
|
42
|
+
exec "rake environment resque:work"
|
43
|
+
|
44
|
+
when 'start'
|
45
|
+
exit(42) unless DATA.flock(File::LOCK_EX | File::LOCK_NB)
|
46
|
+
|
47
|
+
unless running
|
48
|
+
FileUtils.rm_f(pidfile)
|
49
|
+
|
50
|
+
pid = nil
|
51
|
+
a, b = IO.pipe
|
52
|
+
if fork
|
53
|
+
b.close
|
54
|
+
pid = Integer(a.read.strip)
|
55
|
+
a.close
|
56
|
+
puts(pid) unless quiet
|
57
|
+
exit
|
58
|
+
end
|
59
|
+
exit!(0) if fork
|
60
|
+
a.close
|
61
|
+
b.puts(Process.pid)
|
62
|
+
b.close
|
63
|
+
|
64
|
+
{
|
65
|
+
'stdin' => STDIN,
|
66
|
+
'stdout' => STDOUT,
|
67
|
+
'stderr' => STDERR,
|
68
|
+
}.each do |basename, io|
|
69
|
+
path = File.join("log/jobs/#{ basename }")
|
70
|
+
begin
|
71
|
+
open(path, 'a+'){|fd| io.reopen(fd)}
|
72
|
+
rescue
|
73
|
+
open(path, 'w+'){|fd| io.reopen(fd)}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
Process.setsid rescue nil
|
78
|
+
File.umask(0) rescue nil
|
79
|
+
|
80
|
+
# This is where Resque is started...
|
81
|
+
# Looks like a good place to load and run a task that launches a workflow...
|
82
|
+
ENV['PIDFILE'] = pidfile
|
83
|
+
ENV['QUEUE'] = 'jobs'
|
84
|
+
ENV['VVERBOSE'] = '1' if ENV['RAILS_ENV'] != 'production'
|
85
|
+
exec "rake environment resque:work"
|
86
|
+
end
|
87
|
+
|
88
|
+
when 'stop'
|
89
|
+
if running
|
90
|
+
begin
|
91
|
+
Process.kill('-QUIT', pid)
|
92
|
+
rescue Errno::ESRCH
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
when 'shutdown'
|
98
|
+
if running
|
99
|
+
alive = true
|
100
|
+
|
101
|
+
%w( QUIT TERM ).each do |signal|
|
102
|
+
begin
|
103
|
+
Process.kill(signal, pid)
|
104
|
+
rescue Errno::ESRCH
|
105
|
+
nil
|
106
|
+
end
|
107
|
+
|
108
|
+
42.times do
|
109
|
+
begin
|
110
|
+
alive = Process.kill(0, pid)
|
111
|
+
sleep(1 + rand) if alive
|
112
|
+
rescue Errno::ESRCH
|
113
|
+
alive = false
|
114
|
+
break
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
break unless alive
|
119
|
+
end
|
120
|
+
|
121
|
+
if alive
|
122
|
+
begin
|
123
|
+
Process.kill(-9, pid)
|
124
|
+
sleep(rand)
|
125
|
+
rescue Errno::ESRCH
|
126
|
+
nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
when 'restart'
|
132
|
+
exit! if fork
|
133
|
+
exit! if fork
|
134
|
+
system "#{ script } shutdown -q >/dev/null 2>&1"
|
135
|
+
exec "#{ script } start -q >/dev/null 2>&1"
|
136
|
+
|
137
|
+
when 'tail'
|
138
|
+
exec "tail -F ./log/jobs/*"
|
139
|
+
|
140
|
+
when 'pstree'
|
141
|
+
exec "pstree #{ pid }" if running
|
142
|
+
end
|
143
|
+
|
144
|
+
__END__
|
@@ -3,11 +3,20 @@ require 'aws/simple_workflow/decision_task'
|
|
3
3
|
module AWS
|
4
4
|
class SimpleWorkflow
|
5
5
|
module DecisionTaskAdditions
|
6
|
+
def self.extended(inst)
|
7
|
+
inst.class.__send__ :alias_method, :_original_events, :events
|
8
|
+
end
|
9
|
+
|
6
10
|
def scheduled_event(event)
|
7
11
|
events.to_a[event.attributes.scheduled_event_id - 1]
|
8
12
|
end
|
13
|
+
|
14
|
+
def events
|
15
|
+
@__original_events ||= _original_events
|
16
|
+
end
|
17
|
+
|
9
18
|
end
|
10
19
|
|
11
|
-
DecisionTask.__send__(:include, DecisionTaskAdditions)
|
12
20
|
end
|
13
21
|
end
|
22
|
+
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module SimplerWorkflow
|
2
2
|
class Activity
|
3
|
+
include OptionsAsMethods
|
4
|
+
|
3
5
|
attr_reader :domain, :name, :version, :options, :next_activity
|
4
6
|
|
5
7
|
def initialize(domain, name, version, options = {})
|
@@ -20,14 +22,6 @@ module SimplerWorkflow
|
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
|
-
def method_missing(meth_name, *args)
|
24
|
-
if @options.has_key?(meth_name.to_sym)
|
25
|
-
@options[meth_name.to_sym] = args[0]
|
26
|
-
else
|
27
|
-
super
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
25
|
def on_success(activity, version = nil)
|
32
26
|
case activity
|
33
27
|
when Hash
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module SimplerWorkflow
|
2
2
|
class Workflow
|
3
|
+
include OptionsAsMethods
|
4
|
+
|
3
5
|
attr_reader :task_list, :domain, :name, :version, :options, :initial_activity_type
|
4
6
|
|
5
7
|
def initialize(domain, name, version, options = {})
|
@@ -29,7 +31,9 @@ module SimplerWorkflow
|
|
29
31
|
def decision_loop
|
30
32
|
logger.info("Starting decision loop for #{name.to_s}, #{version} listening to #{task_list}")
|
31
33
|
domain.decision_tasks.poll(task_list) do |decision_task|
|
32
|
-
|
34
|
+
start_time = DateTime.now
|
35
|
+
logger.info("Received decision task #{decision_task.id} at #{start_time}")
|
36
|
+
decision_task.extend AWS::SimpleWorkflow::DecisionTaskAdditions
|
33
37
|
decision_task.new_events.each do |event|
|
34
38
|
logger.info("Processing #{event.event_type}")
|
35
39
|
case event.event_type
|
@@ -43,6 +47,7 @@ module SimplerWorkflow
|
|
43
47
|
activity_timed_out(decision_task, event)
|
44
48
|
end
|
45
49
|
end
|
50
|
+
logger.info("Completed Processing Decision Task #{decision_task.id} in #{((DateTime.now - start_time) * 24 * 60 * 60).to_i} seconds.")
|
46
51
|
end
|
47
52
|
rescue Timeout::Error => e
|
48
53
|
retry
|
@@ -141,14 +146,6 @@ module SimplerWorkflow
|
|
141
146
|
workflows[[name, version]] = workflow
|
142
147
|
end
|
143
148
|
|
144
|
-
def method_missing(meth_name, *args)
|
145
|
-
if @options.has_key?(meth_name.to_sym)
|
146
|
-
@options[meth_name.to_sym] = args[0]
|
147
|
-
else
|
148
|
-
super
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
149
|
protected
|
153
150
|
def self.workflows
|
154
151
|
@workflows ||= {}
|
data/lib/simpler_workflow.rb
CHANGED
@@ -3,19 +3,26 @@ require 'aws/simple_workflow/decision_task_additions'
|
|
3
3
|
require 'map'
|
4
4
|
|
5
5
|
module SimplerWorkflow
|
6
|
-
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def domain(domain_name)
|
7
9
|
@domains ||= {}
|
8
10
|
@domains[domain_name.to_sym] ||= Domain.new(domain_name)
|
9
11
|
end
|
10
12
|
|
11
|
-
def
|
13
|
+
def swf
|
12
14
|
@swf ||= ::AWS::SimpleWorkflow.new
|
13
15
|
end
|
14
16
|
|
17
|
+
def logger
|
18
|
+
$logger || Rails.logger
|
19
|
+
end
|
20
|
+
|
15
21
|
autoload :Version, 'simpler_workflow/version'
|
16
22
|
autoload :Domain, 'simpler_workflow/domain'
|
17
23
|
autoload :Workflow, 'simpler_workflow/workflow'
|
18
24
|
autoload :Activity, 'simpler_workflow/activity'
|
25
|
+
autoload :OptionsAsMethods, 'simpler_workflow/options_as_methods'
|
19
26
|
end
|
20
27
|
|
21
28
|
class Map
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simpler_workflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 8
|
10
|
+
version: 0.1.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Frederic Jean
|
@@ -15,12 +15,10 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-07-
|
18
|
+
date: 2012-07-19 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
|
22
|
-
prerelease: false
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
24
22
|
none: false
|
25
23
|
requirements:
|
26
24
|
- - ~>
|
@@ -31,12 +29,12 @@ dependencies:
|
|
31
29
|
- 5
|
32
30
|
- 0
|
33
31
|
version: 1.5.0
|
32
|
+
name: aws-sdk
|
34
33
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: map
|
38
34
|
prerelease: false
|
39
|
-
requirement:
|
35
|
+
requirement: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
40
38
|
none: false
|
41
39
|
requirements:
|
42
40
|
- - ">="
|
@@ -45,12 +43,12 @@ dependencies:
|
|
45
43
|
segments:
|
46
44
|
- 0
|
47
45
|
version: "0"
|
46
|
+
name: map
|
48
47
|
type: :runtime
|
49
|
-
version_requirements: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
name: rake
|
52
48
|
prerelease: false
|
53
|
-
requirement:
|
49
|
+
requirement: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
54
52
|
none: false
|
55
53
|
requirements:
|
56
54
|
- - ">="
|
@@ -59,12 +57,12 @@ dependencies:
|
|
59
57
|
segments:
|
60
58
|
- 0
|
61
59
|
version: "0"
|
60
|
+
name: rake
|
62
61
|
type: :development
|
63
|
-
version_requirements: *id003
|
64
|
-
- !ruby/object:Gem::Dependency
|
65
|
-
name: rspec
|
66
62
|
prerelease: false
|
67
|
-
requirement:
|
63
|
+
requirement: *id003
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
68
66
|
none: false
|
69
67
|
requirements:
|
70
68
|
- - ">="
|
@@ -73,12 +71,12 @@ dependencies:
|
|
73
71
|
segments:
|
74
72
|
- 0
|
75
73
|
version: "0"
|
74
|
+
name: rspec
|
76
75
|
type: :development
|
77
|
-
version_requirements: *id004
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
name: travis-lint
|
80
76
|
prerelease: false
|
81
|
-
requirement:
|
77
|
+
requirement: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
82
80
|
none: false
|
83
81
|
requirements:
|
84
82
|
- - ">="
|
@@ -87,13 +85,15 @@ dependencies:
|
|
87
85
|
segments:
|
88
86
|
- 0
|
89
87
|
version: "0"
|
88
|
+
name: travis-lint
|
90
89
|
type: :development
|
91
|
-
|
90
|
+
prerelease: false
|
91
|
+
requirement: *id005
|
92
92
|
description: A wrapper around Amazon's Simple Workflow Service
|
93
93
|
email:
|
94
94
|
- fred@snugghome.com
|
95
|
-
executables:
|
96
|
-
|
95
|
+
executables:
|
96
|
+
- swf
|
97
97
|
extensions: []
|
98
98
|
|
99
99
|
extra_rdoc_files: []
|
@@ -106,11 +106,13 @@ files:
|
|
106
106
|
- LICENSE
|
107
107
|
- README.md
|
108
108
|
- Rakefile
|
109
|
+
- bin/swf
|
109
110
|
- ext/mkrf_conf.rb
|
110
111
|
- lib/aws/simple_workflow/decision_task_additions.rb
|
111
112
|
- lib/simpler_workflow.rb
|
112
113
|
- lib/simpler_workflow/activity.rb
|
113
114
|
- lib/simpler_workflow/domain.rb
|
115
|
+
- lib/simpler_workflow/options_as_methods.rb
|
114
116
|
- lib/simpler_workflow/version.rb
|
115
117
|
- lib/simpler_workflow/workflow.rb
|
116
118
|
- lib/simpler_workflow/workflow_collection.rb
|