daemonizer 0.4.12 → 0.4.13

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/Rakefile CHANGED
@@ -11,22 +11,36 @@ begin
11
11
  gemspec.homepage = "http://github.com/glebpom/daemonizer"
12
12
  gemspec.authors = ["Gleb Pomykalov"]
13
13
  gemspec.add_dependency('thor', '>= 0.13.7')
14
+ gemspec.add_dependency('simple-statistics', '>= 0')
15
+ gemspec.add_development_dependency "rspec", ">= 1.2.9"
16
+ gemspec.add_development_dependency "yard", ">= 0"
14
17
  end
15
18
  Jeweler::GemcutterTasks.new
16
19
  rescue LoadError
17
20
  puts "Jeweler not available. Install it with: gem install jeweler"
18
21
  end
19
22
 
23
+ require 'spec/rake/spectask'
24
+ Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ spec.libs << 'lib' << 'spec'
26
+ spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ end
28
+
29
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.pattern = 'spec/**/*_spec.rb'
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :spec => :check_dependencies
36
+
37
+ task :default => :spec
38
+
20
39
  begin
21
40
  require 'yard'
22
- YARD::Rake::YardocTask.new(:yard) do |t|
23
- t.options = ['--title', 'Daemonizer Documentation']
24
- if ENV['PRIVATE']
25
- t.options.concat ['--protected', '--private']
26
- else
27
- t.options.concat ['--protected', '--no-private']
28
- end
29
- end
41
+ YARD::Rake::YardocTask.new
30
42
  rescue LoadError
31
- puts 'Yard not available. Install it with: sudo gem install yard'
43
+ task :yardoc do
44
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
45
+ end
32
46
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.12
1
+ 0.4.13
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{daemonizer}
8
- s.version = "0.4.12"
8
+ s.version = "0.4.13"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Gleb Pomykalov"]
12
- s.date = %q{2010-07-29}
12
+ s.date = %q{2010-08-04}
13
13
  s.default_executable = %q{daemonizer}
14
14
  s.description = %q{Inspired by bundler and rack. Mostly built on top of Alexey Kovyrin's loops code. http://github.com/kovyrin/loops}
15
15
  s.email = %q{glebpom@gmail.com}
@@ -39,13 +39,20 @@ Gem::Specification.new do |s|
39
39
  "lib/daemonizer/process_manager.rb",
40
40
  "lib/daemonizer/stats.rb",
41
41
  "lib/daemonizer/worker.rb",
42
- "lib/daemonizer/worker_pool.rb"
42
+ "lib/daemonizer/worker_pool.rb",
43
+ "spec/spec.opts",
44
+ "spec/spec_helper.rb",
45
+ "spec/test_spec.rb"
43
46
  ]
44
47
  s.homepage = %q{http://github.com/glebpom/daemonizer}
45
48
  s.rdoc_options = ["--charset=UTF-8"]
46
49
  s.require_paths = ["lib"]
47
50
  s.rubygems_version = %q{1.3.7}
48
51
  s.summary = %q{Daemonizer allows you to easily create custom daemons on ruby. Supporting prefork model}
52
+ s.test_files = [
53
+ "spec/spec_helper.rb",
54
+ "spec/test_spec.rb"
55
+ ]
49
56
 
50
57
  if s.respond_to? :specification_version then
51
58
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -53,11 +60,20 @@ Gem::Specification.new do |s|
53
60
 
54
61
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
55
62
  s.add_runtime_dependency(%q<thor>, [">= 0.13.7"])
63
+ s.add_runtime_dependency(%q<simple-statistics>, [">= 0"])
64
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
65
+ s.add_development_dependency(%q<yard>, [">= 0"])
56
66
  else
57
67
  s.add_dependency(%q<thor>, [">= 0.13.7"])
68
+ s.add_dependency(%q<simple-statistics>, [">= 0"])
69
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
70
+ s.add_dependency(%q<yard>, [">= 0"])
58
71
  end
59
72
  else
60
73
  s.add_dependency(%q<thor>, [">= 0.13.7"])
74
+ s.add_dependency(%q<simple-statistics>, [">= 0"])
75
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
76
+ s.add_dependency(%q<yard>, [">= 0"])
61
77
  end
62
78
  end
63
79
 
@@ -3,6 +3,7 @@ require 'yaml'
3
3
  require 'erb'
4
4
  require 'pathname'
5
5
  require 'logger'
6
+ require 'simple-statistics'
6
7
 
7
8
  module Daemonizer
8
9
 
@@ -85,7 +85,10 @@ module Daemonizer
85
85
 
86
86
  desc "debug", "Debug pool (do not demonize)"
87
87
  def debug(pool_name = nil)
88
- puts "You should supply pool_name to debug" if pool_name.nil?
88
+ if pool_name.nil?
89
+ puts "You should supply pool_name to debug"
90
+ exit 1
91
+ end
89
92
  control_pools_loop(pool_name, "execution ended", true) do |pool|
90
93
  STDOUT.sync = true
91
94
 
@@ -32,6 +32,7 @@ module Daemonizer
32
32
  @options[:handler] ||= nil
33
33
  @options[:handler_options] ||= {}
34
34
  @options[:callbacks] ||= {}
35
+ @options[:on_poll] ||= []
35
36
  @options[:cow_friendly] = true if @options[:cow_friendly].nil?
36
37
  end
37
38
 
@@ -70,7 +71,7 @@ module Daemonizer
70
71
  validate_file(self.pid_file)
71
72
  end
72
73
 
73
- [:workers, :poll_period, :root, :cow_friendly, :callbacks, :handler_options].each do |method|
74
+ [:workers, :poll_period, :root, :cow_friendly, :callbacks, :handler_options, :on_poll].each do |method|
74
75
  define_method method do
75
76
  @options[method.to_sym]
76
77
  end
@@ -39,6 +39,12 @@ class Daemonizer::Dsl
39
39
  end
40
40
  end
41
41
 
42
+ def on_poll(&block)
43
+ @options[:on_poll] ||= []
44
+ @options[:on_poll] << block
45
+ end
46
+
47
+
42
48
  def not_cow_friendly
43
49
  @options[:cow_friendly] = false
44
50
  end
@@ -94,6 +100,7 @@ class Daemonizer::Dsl
94
100
  options = @options.dup
95
101
  options[:handler_options] = @options[:handler_options].dup if @options[:handler_options]
96
102
  options[:callbacks] = @options[:callbacks].dup if @options[:callbacks]
103
+ options[:on_poll] = @options[:on_poll].dup if @options[:on_poll]
97
104
  options
98
105
  end
99
106
  end
@@ -32,11 +32,8 @@ module Daemonizer
32
32
  end
33
33
 
34
34
  def prepare(starter, &block)
35
- if @prepare
36
- @prepare.call(block)
37
- else
38
- super
39
- end
35
+ @prepare.call(block) if @prepare
36
+ super
40
37
  end
41
38
 
42
39
  def start
@@ -1,7 +1,6 @@
1
1
  module Daemonizer
2
2
  class ProcessManager
3
3
  def initialize(config)
4
- @worker_pools = {}
5
4
  @shutdown = false
6
5
  @config = config
7
6
  end
@@ -10,8 +9,8 @@ module Daemonizer
10
9
  def start_workers(&blk)
11
10
  raise ArgumentError, "Need a worker block!" unless block_given?
12
11
  Daemonizer.logger.info "starting all workers"
13
- @worker_pools[@config.pool] = WorkerPool.new(@config.pool, self, &blk)
14
- @worker_pools[@config.pool].start_workers(@config.workers)
12
+ @pool = WorkerPool.new(@config.pool, self, &blk)
13
+ @pool.start_workers(@config.workers)
15
14
  end
16
15
 
17
16
  def monitor_workers
@@ -20,15 +19,20 @@ module Daemonizer
20
19
  Daemonizer.logger.debug 'Starting workers monitoring code...'
21
20
  loop do
22
21
  Daemonizer.logger.debug "Checking workers' health..."
23
- @worker_pools.each do |name, pool|
24
- break if shutdown?
25
- pool.check_workers
22
+ break if shutdown?
23
+ @pool.check_workers
24
+
25
+ @config.on_poll.each do |on_poll|
26
+ on_poll.call(@pool)
26
27
  end
27
28
 
28
29
  break if shutdown?
29
30
  Daemonizer.logger.debug "Sleeping for #{@config.poll_period} seconds..."
30
31
  sleep(@config.poll_period)
31
32
  end
33
+ rescue Exception => e
34
+ Daemonizer.logger.fatal "Monitor error: #{e.to_s}\n #{e.backtrace.join("\n ")}"
35
+ raise
32
36
  ensure
33
37
  Daemonizer.logger.debug "Workers monitoring loop is finished, starting shutdown..."
34
38
  # Send out stop signals
@@ -51,11 +55,7 @@ module Daemonizer
51
55
  def wait_for_workers(seconds)
52
56
  seconds.times do
53
57
  Daemonizer.logger.debug "Shutting down... waiting for workers to die (we have #{seconds} seconds)..."
54
- running_total = 0
55
-
56
- @worker_pools.each do |name, pool|
57
- running_total += pool.wait_workers
58
- end
58
+ running_total = @pool.wait_workers
59
59
 
60
60
  if running_total.zero?
61
61
  Daemonizer.logger.debug "All workers are dead. Exiting..."
@@ -69,14 +69,12 @@ module Daemonizer
69
69
  return false
70
70
  end
71
71
 
72
- def stop_workers(force = false)
72
+ def stop_workers(force = false)
73
73
  # Set shutdown flag
74
74
  Daemonizer.logger.debug "Stopping workers#{force ? ' (forced)' : ''}..."
75
75
 
76
76
  # Termination loop
77
- @worker_pools.each do |name, pool|
78
- pool.stop_workers(force)
79
- end
77
+ @pool.stop_workers(force)
80
78
  end
81
79
 
82
80
  def shutdown?
@@ -180,6 +180,7 @@ module Daemonizer::Stats
180
180
  #
181
181
  # # Search by process name.
182
182
  # list_processes(:match => 'Passenger FrameworkSpawner')
183
+
183
184
  def list_processes(options)
184
185
  if options[:exe]
185
186
  name = options[:exe].sub(/.*\/(.*)/, '\1')
@@ -1,6 +1,7 @@
1
1
  module Daemonizer
2
2
  class Worker
3
3
  attr_reader :name
4
+ attr_reader :process_name
4
5
  attr_reader :pid
5
6
 
6
7
  def initialize(name, pm, worker_id, &blk)
@@ -10,6 +11,7 @@ module Daemonizer
10
11
  @pm = pm
11
12
  @worker_block = blk
12
13
  @worker_id = worker_id
14
+ @process_name = "#{@name} worker: instance #{@worker_id}"
13
15
  end
14
16
 
15
17
  def shutdown?
@@ -34,7 +36,7 @@ module Daemonizer
34
36
  Daemonizer.logger.info "Log file reopened after fork"
35
37
  normal_exit = false
36
38
  begin
37
- $0 = "#{@name} worker: instance #{@worker_id}\0"
39
+ $0 = "#{@process_name}\0"
38
40
  @worker_block.call(@worker_id)
39
41
  normal_exit = true
40
42
  exit(0)
@@ -1,12 +1,22 @@
1
1
  module Daemonizer
2
2
  class WorkerPool
3
+ MONITOR_VALUE = [:vm_size, :private_dirty_rss, :rss]
4
+
3
5
  attr_reader :name
6
+ attr_reader :stats
4
7
 
5
8
  def initialize(name, pm, &blk)
6
9
  @name = name
7
10
  @pm = pm
8
11
  @worker_block = blk
9
12
  @workers = []
13
+ @stats = ::SimpleStatistics::DataSet.new
14
+ end
15
+
16
+ def find_worker_by_name(name)
17
+ @workers.detect do |w|
18
+ w.process_name.to_s == name.to_s
19
+ end
10
20
  end
11
21
 
12
22
  def shutdown?
@@ -16,19 +26,39 @@ module Daemonizer
16
26
  def start_workers(number)
17
27
  Daemonizer.logger.debug "Creating #{number} workers for #{name} pool..."
18
28
  number.times do |i|
19
- @workers << Worker.new(name, @pm, i+1, &@worker_block)
29
+ worker = Worker.new(name, @pm, i+1, &@worker_block)
30
+ @workers << worker
31
+ @stats.add_data(worker.process_name)
32
+ Daemonizer.logger.info "Gathering data for #{worker.name}"
20
33
  end
34
+ rescue Exception => e
35
+ Daemonizer.logger.info "Result - #{e.inspect}"
21
36
  end
22
37
 
23
38
  def check_workers
24
39
  Daemonizer.logger.debug "Checking loop #{name} workers..."
40
+
41
+ Daemonizer::Stats::MemoryStats.new(self).find_workers.each do |p|
42
+ worker_name = p.name
43
+ MONITOR_VALUE.each do |value|
44
+ @stats.tick(value)
45
+ @stats[worker_name][value].add_probe(p.send(value))
46
+ end
47
+ end
48
+
25
49
  @workers.each do |worker|
26
- next if worker.running? || worker.shutdown?
27
- Daemonizer.logger.warn "Worker #{worker.name} is not running. Restart!"
28
- worker.run
50
+ unless worker.running? || worker.shutdown?
51
+ Daemonizer.logger.warn "Worker #{worker.name} is not running. Restart!"
52
+ @stats.add_data(worker.process_name)
53
+ MONITOR_VALUE.each do |v|
54
+ @stats[worker.process_name].reset(v)
55
+ end
56
+ worker.run
57
+ end
29
58
  end
30
59
  end
31
60
 
61
+
32
62
  def wait_workers
33
63
  running = 0
34
64
  @workers.each do |worker|
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'test'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Configuration" do
4
+
5
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: daemonizer
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 12
10
- version: 0.4.12
9
+ - 13
10
+ version: 0.4.13
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gleb Pomykalov
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-07-29 00:00:00 +04:00
18
+ date: 2010-08-04 00:00:00 +04:00
19
19
  default_executable: daemonizer
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -34,6 +34,50 @@ dependencies:
34
34
  version: 0.13.7
35
35
  type: :runtime
36
36
  version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: simple-statistics
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: rspec
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 13
60
+ segments:
61
+ - 1
62
+ - 2
63
+ - 9
64
+ version: 1.2.9
65
+ type: :development
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: yard
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ type: :development
80
+ version_requirements: *id004
37
81
  description: Inspired by bundler and rack. Mostly built on top of Alexey Kovyrin's loops code. http://github.com/kovyrin/loops
38
82
  email: glebpom@gmail.com
39
83
  executables:
@@ -65,6 +109,9 @@ files:
65
109
  - lib/daemonizer/stats.rb
66
110
  - lib/daemonizer/worker.rb
67
111
  - lib/daemonizer/worker_pool.rb
112
+ - spec/spec.opts
113
+ - spec/spec_helper.rb
114
+ - spec/test_spec.rb
68
115
  has_rdoc: true
69
116
  homepage: http://github.com/glebpom/daemonizer
70
117
  licenses: []
@@ -99,5 +146,6 @@ rubygems_version: 1.3.7
99
146
  signing_key:
100
147
  specification_version: 3
101
148
  summary: Daemonizer allows you to easily create custom daemons on ruby. Supporting prefork model
102
- test_files: []
103
-
149
+ test_files:
150
+ - spec/spec_helper.rb
151
+ - spec/test_spec.rb