sponges 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -56,15 +56,14 @@ class Worker
56
56
  end
57
57
 
58
58
  Sponges.configure do |config|
59
- config.worker = Worker.new # mandatory
60
- config.worker_name = "bob" # mandatory
61
- config.worker_method = :run # mandatory
62
- config.worker_args = {first: true} # mandatory
63
59
  config.logger = MyCustomLogger.new # optionnal
64
60
  config.redis = Redis.new # optionnal
65
61
  end
66
62
 
67
- Sponges.start
63
+ # Register a pool named "worker_name".
64
+ Sponges.start "worker_name" do
65
+ Worker.new({some: args}).run
66
+ end
68
67
  ```
69
68
  See the help message :
70
69
  ``` bash
@@ -83,7 +82,7 @@ ruby example.rb start -d
83
82
 
84
83
  Start 8 instances of the worker and daemonize them:
85
84
  ``` bash
86
- ruby example.rb start -d -s 8
85
+ ruby example.rb start -d -s 8 # By default, size equals cpu core's size.
87
86
  ```
88
87
 
89
88
  Retart gracefully 4 instances of the worker and daemonize them:
@@ -118,10 +117,11 @@ Show a list of workers and their children.
118
117
  ruby example.rb list
119
118
  ```
120
119
 
121
- ## TODO
120
+ ## Acknowledgements
122
121
 
123
- * More specs.
124
- * Check on OSX.
122
+ sponges would not have been the same without [Jesse
123
+ Storimer](https://github.com/jstorimer) and his awesome book about
124
+ [Unix](http://workingwithunixprocesses.com/).
125
125
 
126
126
  ## Copyright
127
127
 
@@ -5,7 +5,6 @@ require 'logger'
5
5
  require 'nest'
6
6
  require 'machine'
7
7
  require_relative 'sponges/configuration'
8
- require_relative 'sponges/worker_builder'
9
8
  require_relative 'sponges/supervisor'
10
9
  require_relative 'sponges/runner'
11
10
  require_relative 'sponges/commander'
@@ -19,7 +18,9 @@ module Sponges
19
18
  end
20
19
  module_function :configure
21
20
 
22
- def start(options = ARGV)
21
+ def start(worker_name, options = ARGV, &block)
22
+ Sponges::Configuration.worker_name = worker_name
23
+ Sponges::Configuration.worker = block
23
24
  Sponges::Cli.start(options)
24
25
  end
25
26
  module_function :start
@@ -7,29 +7,24 @@ module Sponges
7
7
  option :size, type: :numeric
8
8
  desc "Start workers"
9
9
  def start(options = {})
10
- worker = Sponges::Runner.new(Sponges::Configuration.worker_name, options)
11
- if Sponges::Configuration.worker_args
12
- worker.work(Sponges::Configuration.worker, Sponges::Configuration.worker_method,
13
- Sponges::Configuration.worker_args)
14
- else
15
- worker.work(Sponges::Configuration.worker, Sponges::Configuration.worker_method)
16
- end
10
+ Sponges::Runner.new(Sponges::Configuration.worker_name, options,
11
+ Sponges::Configuration.worker
12
+ ).start
17
13
  end
18
14
 
19
15
  option :gracefully, type: :boolean
20
16
  desc "Stop workers"
21
17
  def stop(options = {})
22
- Sponges::Commander.new(Sponges::Configuration.worker_name, options).
23
- stop
18
+ Sponges::Commander.new(Sponges::Configuration.worker_name, options).stop
24
19
  end
25
20
 
26
21
  option :daemonize, type: :boolean
27
22
  option :size, type: :numeric
28
23
  option :gracefully, type: :boolean
29
24
  desc "Restart workers"
30
- def restart(options = {})
25
+ def restart(options = {}, &block)
31
26
  stop(options)
32
- start(options)
27
+ start(options, block)
33
28
  end
34
29
 
35
30
  desc "Increment workers pool size"
@@ -4,7 +4,7 @@ module Sponges
4
4
  #
5
5
  class Configuration
6
6
  class << self
7
- ACCESSOR = [:worker_name, :worker, :worker_method, :worker_args, :logger, :redis]
7
+ ACCESSOR = [:worker_name, :worker, :logger, :redis]
8
8
  attr_accessor *ACCESSOR
9
9
 
10
10
  def configure
@@ -4,20 +4,24 @@ module Sponges
4
4
  # watch over the supervisor.
5
5
  #
6
6
  class Runner
7
- def initialize(name, options = {})
8
- @name = name
7
+ def initialize(name, options = {}, block)
8
+ @name, @block = name, block
9
9
  @options = default_options.merge options
10
10
  @redis = Nest.new('sponges', Configuration.redis || Redis.new)
11
+ if running?
12
+ Sponges.logger.error "Runner #{@name} already started."
13
+ exit
14
+ end
11
15
  @redis[:hostnames].sadd Socket.gethostname
12
16
  end
13
17
 
14
- def work(worker, method, *args, &block)
18
+ def start
15
19
  if daemonize?
16
20
  Sponges.logger.info "Supervisor daemonized."
17
21
  Process.daemon
18
22
  end
19
23
  Sponges.logger.info "Runner #{@name} start message received."
20
- @supervisor = fork_supervisor(worker, method, *args, &block)
24
+ @supervisor = fork_supervisor
21
25
  trap_signals
22
26
  Sponges.logger.info "Supervisor started with #{@supervisor} pid."
23
27
  Process.waitpid(@supervisor) unless daemonize?
@@ -25,6 +29,20 @@ module Sponges
25
29
 
26
30
  private
27
31
 
32
+ def running?
33
+ if pid = @redis[Socket.gethostname][:worker][@name][:supervisor].get
34
+ begin
35
+ Process.kill 0, pid.to_i
36
+ true
37
+ rescue Errno::ESRCH => e
38
+ @redis[Socket.gethostname][:worker][@name][:supervisor].del
39
+ false
40
+ end
41
+ else
42
+ false
43
+ end
44
+ end
45
+
28
46
  def trap_signals
29
47
  Sponges::SIGNALS.each do |signal|
30
48
  trap(signal) {|signal| kill_supervisor(signal) }
@@ -42,10 +60,10 @@ module Sponges
42
60
  }
43
61
  end
44
62
 
45
- def fork_supervisor(worker, method, *args, &block)
63
+ def fork_supervisor
46
64
  fork do
47
65
  $PROGRAM_NAME = "#{@name}_supervisor"
48
- Supervisor.new(@name, @options, worker, method, *args, &block).start
66
+ Supervisor.new(@name, @options, @block).start
49
67
  end
50
68
  end
51
69
 
@@ -1,9 +1,8 @@
1
1
  # encoding: utf-8
2
2
  module Sponges
3
3
  class Supervisor
4
- def initialize(name, options, worker, method, *args, &block)
5
- @name, @options = name, options
6
- @worker, @method, @args, @block = worker, method, args, block
4
+ def initialize(name, options, block)
5
+ @name, @options, @block = name, options, block
7
6
  set_up_redis
8
7
  @pids = @redis[:worker][name][:pids]
9
8
  @children_seen = 0
@@ -37,7 +36,7 @@ module Sponges
37
36
  name = children_name
38
37
  pid = fork do
39
38
  $PROGRAM_NAME = name
40
- Sponges::WorkerBuilder.new(@worker, @method, *@args, &@block).start
39
+ @block.call
41
40
  end
42
41
  Sponges.logger.info "Supervisor create a child with #{pid} pid."
43
42
  @pids.sadd pid
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Sponges
3
- VERSION = "0.0.6"
3
+ VERSION = "0.1.0"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sponges
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-16 00:00:00.000000000 Z
12
+ date: 2012-10-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: boson
@@ -93,7 +93,6 @@ files:
93
93
  - lib/sponges/runner.rb
94
94
  - lib/sponges/supervisor.rb
95
95
  - lib/sponges/version.rb
96
- - lib/sponges/worker_builder.rb
97
96
  homepage: https://github.com/AF83/sponges
98
97
  licenses: []
99
98
  post_install_message:
@@ -1,29 +0,0 @@
1
- # encoding: utf-8
2
- module Sponges
3
- # This class concern is to build a worker instance, set some signals handlers
4
- # and make it start its job.
5
- #
6
- class WorkerBuilder
7
- def initialize(worker, method, *args, &block)
8
- @worker, @method, @args, @block = worker, method, args, block
9
- end
10
-
11
- def start
12
- trap_signals
13
- at_exit do
14
- Sponges.logger.info "Child exits."
15
- end
16
- @worker.send(@method, *@args, &@block)
17
- end
18
-
19
- private
20
-
21
- def trap_signals
22
- Sponges::SIGNALS.each do |signal|
23
- trap(signal) do
24
- exit 0
25
- end
26
- end
27
- end
28
- end
29
- end