sisyphus 0.2.2 → 0.2.3
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/Gemfile.lock +1 -1
- data/README.md +8 -3
- data/lib/sisyphus/master.rb +18 -5
- data/lib/sisyphus/null_logger.rb +11 -0
- data/lib/sisyphus/worker.rb +14 -7
- data/lib/version.rb +1 -1
- data/spec/sisyphus/master_spec.rb +28 -2
- data/spec/sisyphus/worker_spec.rb +13 -4
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1a96cdf599669e601888f70c06de7ae280b86fc6
|
|
4
|
+
data.tar.gz: 601d5544f93601e4b9aac5df9dad122040742300
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 731a337d88e4ca319a824c2fdb44f2343808adfd1a15762bfb6a2417666c7aca8182b2859bf495c33f4c48c170091061b36f18fb0088281258288fe677a5d55a
|
|
7
|
+
data.tar.gz: e4c2bcbfb26349558d25d705fb69f370cc05e4040f8f46bc4430794b448b1e621bcece6988b68318a2ee6dba128594001cd42f2212bf52ac9ec79125e9704afc
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -22,11 +22,16 @@ the job receives the `perform` message.
|
|
|
22
22
|
Getting started
|
|
23
23
|
---------------
|
|
24
24
|
|
|
25
|
-
1. Add `gem '
|
|
25
|
+
1. Add `gem 'sisyphus'` to your Gemfile and run `bundle`
|
|
26
26
|
2. Subclass `Sisyphus::Job` and implement the `perform` method
|
|
27
27
|
3. Instantiate the `Sisyphus::Master`, giving it an instance of your job
|
|
28
|
-
and optionally an options hash
|
|
29
|
-
|
|
28
|
+
and optionally an `options` hash. The `options` hash supports the
|
|
29
|
+
following keys:
|
|
30
|
+
* `:workers` which specifies the number (`FixNum`) of workers you need.
|
|
31
|
+
* `:logger` which is used to log any exceptions the
|
|
32
|
+
master or workers encounter. The logger should quack like a
|
|
33
|
+
`Logger` instance from the Ruby stdlib. Exceptions are logged with the
|
|
34
|
+
`Logger::WARN` level.
|
|
30
35
|
4. You can start workers by doing one of the following things:
|
|
31
36
|
* Send the `start` message to the master, if the `options` hash was
|
|
32
37
|
provided. This starts a run loop which monitors workers and
|
data/lib/sisyphus/master.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'timeout'
|
|
2
2
|
require_relative './worker'
|
|
3
|
+
require_relative './null_logger'
|
|
3
4
|
|
|
4
5
|
module Sisyphus
|
|
5
6
|
class Master
|
|
@@ -7,8 +8,11 @@ module Sisyphus
|
|
|
7
8
|
|
|
8
9
|
HANDLED_SIGNALS = [:INT, :TTIN, :TTOU]
|
|
9
10
|
|
|
11
|
+
attr_reader :logger
|
|
12
|
+
|
|
10
13
|
def initialize(job, options = {})
|
|
11
14
|
@number_of_workers = options.fetch :workers, 0
|
|
15
|
+
@logger = options.fetch :logger, NullLogger.new
|
|
12
16
|
@workers = []
|
|
13
17
|
@job = job
|
|
14
18
|
|
|
@@ -35,17 +39,22 @@ module Sisyphus
|
|
|
35
39
|
@workers << { pid: wpid, reader: reader }
|
|
36
40
|
else
|
|
37
41
|
reader.close
|
|
38
|
-
worker = Worker.new(@job, writer)
|
|
39
42
|
self.process_name = "Worker #{Process.pid}"
|
|
40
|
-
|
|
43
|
+
begin
|
|
44
|
+
worker = Worker.new(@job, writer, logger)
|
|
45
|
+
worker.setup
|
|
46
|
+
worker.start
|
|
47
|
+
rescue Exception => e
|
|
48
|
+
writer.write Worker::UNCAUGHT_ERROR
|
|
49
|
+
logger.warn(process_name) { e }
|
|
50
|
+
exit! 0
|
|
51
|
+
end
|
|
41
52
|
end
|
|
42
53
|
end
|
|
43
54
|
|
|
44
55
|
def stop_worker(wpid)
|
|
45
56
|
if @workers.find { |w| w.fetch(:pid) == wpid }
|
|
46
|
-
Process.kill 'INT', wpid
|
|
47
|
-
else
|
|
48
|
-
raise "Unknown worker PID: #{wpid}"
|
|
57
|
+
Process.kill 'INT', wpid rescue Errno::ESRCH # Ignore if the process is already gone
|
|
49
58
|
end
|
|
50
59
|
end
|
|
51
60
|
|
|
@@ -184,5 +193,9 @@ module Sisyphus
|
|
|
184
193
|
def process_name=(name)
|
|
185
194
|
$0 = name
|
|
186
195
|
end
|
|
196
|
+
|
|
197
|
+
def process_name
|
|
198
|
+
$0
|
|
199
|
+
end
|
|
187
200
|
end
|
|
188
201
|
end
|
data/lib/sisyphus/worker.rb
CHANGED
|
@@ -2,10 +2,16 @@ module Sisyphus
|
|
|
2
2
|
class Worker
|
|
3
3
|
UNCAUGHT_ERROR = '.'
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
attr_reader :logger
|
|
6
|
+
|
|
7
|
+
def initialize(job, output, logger)
|
|
6
8
|
@job = job
|
|
7
9
|
@output = output
|
|
8
|
-
|
|
10
|
+
@logger = logger
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def setup
|
|
14
|
+
@job.setup if @job.respond_to? :setup
|
|
9
15
|
end
|
|
10
16
|
|
|
11
17
|
def start
|
|
@@ -34,7 +40,8 @@ module Sisyphus
|
|
|
34
40
|
begin
|
|
35
41
|
@job.perform
|
|
36
42
|
exit! 0
|
|
37
|
-
rescue Exception
|
|
43
|
+
rescue Exception => e
|
|
44
|
+
logger.warn(process_name) { e }
|
|
38
45
|
exit! 1
|
|
39
46
|
end
|
|
40
47
|
end
|
|
@@ -54,12 +61,12 @@ module Sisyphus
|
|
|
54
61
|
@stopped
|
|
55
62
|
end
|
|
56
63
|
|
|
57
|
-
def setup
|
|
58
|
-
@job.setup if @job.respond_to? :setup
|
|
59
|
-
end
|
|
60
|
-
|
|
61
64
|
def process_name=(name)
|
|
62
65
|
$0 = name
|
|
63
66
|
end
|
|
67
|
+
|
|
68
|
+
def process_name
|
|
69
|
+
$0
|
|
70
|
+
end
|
|
64
71
|
end
|
|
65
72
|
end
|
data/lib/version.rb
CHANGED
|
@@ -25,9 +25,15 @@ module Sisyphus
|
|
|
25
25
|
Process.stub(:pid) { 666 }
|
|
26
26
|
master.stub :exit!
|
|
27
27
|
Worker.stub(:new) { worker }
|
|
28
|
+
worker.stub(:setup)
|
|
28
29
|
worker.stub(:start)
|
|
29
30
|
end
|
|
30
31
|
|
|
32
|
+
it 'should setup the worker' do
|
|
33
|
+
worker.should_receive :setup
|
|
34
|
+
master.start_worker
|
|
35
|
+
end
|
|
36
|
+
|
|
31
37
|
it 'should rename the process' do
|
|
32
38
|
master.should_receive(:process_name=).with("Worker #{666}")
|
|
33
39
|
master.start_worker
|
|
@@ -39,7 +45,7 @@ module Sisyphus
|
|
|
39
45
|
end
|
|
40
46
|
|
|
41
47
|
it 'gives the writer pipe to the worker' do
|
|
42
|
-
Worker.should_receive(:new).with(job, pipes.last) { worker }
|
|
48
|
+
Worker.should_receive(:new).with(job, pipes.last, master.logger) { worker }
|
|
43
49
|
master.start_worker
|
|
44
50
|
end
|
|
45
51
|
|
|
@@ -47,6 +53,26 @@ module Sisyphus
|
|
|
47
53
|
pipes.first.should_receive :close
|
|
48
54
|
master.start_worker
|
|
49
55
|
end
|
|
56
|
+
|
|
57
|
+
describe 'when an exception is raised' do
|
|
58
|
+
let(:logger) { double(:logger) }
|
|
59
|
+
|
|
60
|
+
it 'should log the exception' do
|
|
61
|
+
master.stub(:logger).and_return logger
|
|
62
|
+
pipes.last.stub(:write)
|
|
63
|
+
worker.stub(:setup).and_raise :raised_by_spec
|
|
64
|
+
logger.should_receive :warn
|
|
65
|
+
master.start_worker
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'should write to the writer pipe' do
|
|
69
|
+
master.stub(:logger).and_return logger
|
|
70
|
+
worker.stub(:setup).and_raise :raised_by_spec
|
|
71
|
+
logger.stub :warn
|
|
72
|
+
pipes.last.should_receive(:write).with Worker::UNCAUGHT_ERROR
|
|
73
|
+
master.start_worker
|
|
74
|
+
end
|
|
75
|
+
end
|
|
50
76
|
end
|
|
51
77
|
|
|
52
78
|
describe 'in the master process' do
|
|
@@ -103,7 +129,7 @@ module Sisyphus
|
|
|
103
129
|
describe 'when there are no running workers' do
|
|
104
130
|
describe 'and it receives stop_worker' do
|
|
105
131
|
it 'raises an error' do
|
|
106
|
-
expect { master.stop_worker(666) }.
|
|
132
|
+
expect { master.stop_worker(666) }.not_to raise_error
|
|
107
133
|
end
|
|
108
134
|
end
|
|
109
135
|
|
|
@@ -4,7 +4,8 @@ module Sisyphus
|
|
|
4
4
|
describe Worker do
|
|
5
5
|
let(:job) { double :job }
|
|
6
6
|
let(:output) { double :pipe }
|
|
7
|
-
let(:
|
|
7
|
+
let(:logger) { double :logger }
|
|
8
|
+
let(:worker) { Worker.new job, output, logger }
|
|
8
9
|
|
|
9
10
|
it 'traps signals when started' do
|
|
10
11
|
worker.stub :exit!
|
|
@@ -23,15 +24,15 @@ module Sisyphus
|
|
|
23
24
|
it 'does not call job.setup' do
|
|
24
25
|
job.stub(:respond_to?).with(:setup) { false }
|
|
25
26
|
job.should_not_receive :setup
|
|
26
|
-
Worker.new job, output
|
|
27
|
+
Worker.new job, output, logger
|
|
27
28
|
end
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
context 'when job responds to :setup' do
|
|
31
|
-
it 'sets up the job
|
|
32
|
+
it 'sets up the job' do
|
|
32
33
|
job.stub(:respond_to?).with(:setup) { true }
|
|
33
34
|
job.should_receive :setup
|
|
34
|
-
|
|
35
|
+
worker.setup
|
|
35
36
|
end
|
|
36
37
|
end
|
|
37
38
|
|
|
@@ -62,10 +63,18 @@ module Sisyphus
|
|
|
62
63
|
|
|
63
64
|
context 'when job.perform raises an error' do
|
|
64
65
|
it 'should exit with a non-zero status' do
|
|
66
|
+
logger.stub :warn
|
|
65
67
|
job.stub(:perform).and_raise Exception.new "should be rescued!"
|
|
66
68
|
worker.should_receive(:exit!).with(1)
|
|
67
69
|
worker.send :perform_job
|
|
68
70
|
end
|
|
71
|
+
|
|
72
|
+
it 'should log the raised error' do
|
|
73
|
+
worker.stub(:exit!).with(1)
|
|
74
|
+
job.stub(:perform).and_raise Exception.new "should be rescued!"
|
|
75
|
+
logger.should_receive :warn
|
|
76
|
+
worker.send :perform_job
|
|
77
|
+
end
|
|
69
78
|
end
|
|
70
79
|
end
|
|
71
80
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sisyphus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rasmus Bang Grouleff
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2013-
|
|
11
|
+
date: 2013-12-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -68,6 +68,7 @@ files:
|
|
|
68
68
|
- lib/sisyphus.rb
|
|
69
69
|
- lib/sisyphus/job.rb
|
|
70
70
|
- lib/sisyphus/master.rb
|
|
71
|
+
- lib/sisyphus/null_logger.rb
|
|
71
72
|
- lib/sisyphus/sleep.rb
|
|
72
73
|
- lib/sisyphus/worker.rb
|
|
73
74
|
- lib/version.rb
|