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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 09c4ed5586564bbe862e247e22ade9cf3b8d0d91
4
- data.tar.gz: 89cb27f90e6b9b62e7152cea92866ef3b88f83f1
3
+ metadata.gz: 1a96cdf599669e601888f70c06de7ae280b86fc6
4
+ data.tar.gz: 601d5544f93601e4b9aac5df9dad122040742300
5
5
  SHA512:
6
- metadata.gz: 1835644e1bb451fa689024a33fba8e1e12f2f6ce6ded605611b4564117ae09f0c67f58c749f984c271ef8eab2509da5f56f3c832e11a3fcf08036830c0503797
7
- data.tar.gz: 823fb159c29104d485fa6f7320b2340de260fb36d463cd80096d3c78d45e275687d6b30ccf3c5dcdb238dfaabea886d9a9912ccc5e7f2a1ca2a1c3a948e007f0
6
+ metadata.gz: 731a337d88e4ca319a824c2fdb44f2343808adfd1a15762bfb6a2417666c7aca8182b2859bf495c33f4c48c170091061b36f18fb0088281258288fe677a5d55a
7
+ data.tar.gz: e4c2bcbfb26349558d25d705fb69f370cc05e4040f8f46bc4430794b448b1e621bcece6988b68318a2ee6dba128594001cd42f2212bf52ac9ec79125e9704afc
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sisyphus (0.2.1)
4
+ sisyphus (0.2.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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 'coolie'` to your Gemfile and run `bundle`
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 with the key `:workers` specifying the
29
- number of workers you need
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
@@ -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
- worker.start
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
@@ -0,0 +1,11 @@
1
+ require 'logger'
2
+
3
+ module Sisyphus
4
+ class NullLogger < Logger
5
+ def initialize(*args)
6
+ end
7
+
8
+ def add(*args, &block)
9
+ end
10
+ end
11
+ end
@@ -2,10 +2,16 @@ module Sisyphus
2
2
  class Worker
3
3
  UNCAUGHT_ERROR = '.'
4
4
 
5
- def initialize(job, output)
5
+ attr_reader :logger
6
+
7
+ def initialize(job, output, logger)
6
8
  @job = job
7
9
  @output = output
8
- setup
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
@@ -1,3 +1,3 @@
1
1
  module Sisyphus
2
- VERSION = "0.2.2"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -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) }.to raise_error("Unknown worker PID: #{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(:worker) { Worker.new job, output }
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 upon initialization' do
32
+ it 'sets up the job' do
32
33
  job.stub(:respond_to?).with(:setup) { true }
33
34
  job.should_receive :setup
34
- Worker.new job, output
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.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-10-29 00:00:00.000000000 Z
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