sponges 0.0.6 → 0.1.0

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/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