daemonizer 0.4.12 → 0.4.13

Sign up to get free protection for your applications and to get access to all the features.
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