daemonizer 0.4.18 → 0.5.0.beta.1

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.
@@ -21,13 +21,13 @@ module Daemonizer
21
21
  Daemonizer.logger.debug "Checking workers' health..."
22
22
  break if shutdown?
23
23
  @pool.check_workers
24
-
24
+
25
25
  @config.on_poll.each do |on_poll|
26
26
  on_poll.call(@pool)
27
27
  end
28
28
 
29
29
  break if shutdown?
30
- Daemonizer.logger.debug "Sleeping for #{@config.poll_period} seconds..."
30
+ Daemonizer.logger.debug "Sleeping for #{@config.poll_period} seconds..."
31
31
  sleep(@config.poll_period)
32
32
  end
33
33
  rescue Exception => e
@@ -69,7 +69,7 @@ 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
 
@@ -77,6 +77,10 @@ module Daemonizer
77
77
  @pool.stop_workers(force)
78
78
  end
79
79
 
80
+ def send_signal_to_workers(signal)
81
+ @pool.send_signal_to_workers(signal)
82
+ end
83
+
80
84
  def shutdown?
81
85
  @shutdown
82
86
  end
@@ -0,0 +1,3 @@
1
+ module Daemonizer
2
+ VERSION = "0.5.0.beta.1"
3
+ end
@@ -28,11 +28,13 @@ module Daemonizer
28
28
  STDIN.reopen '/dev/null'
29
29
  STDOUT.reopen '/dev/null', 'a'
30
30
  STDERR.reopen STDOUT
31
-
31
+
32
+ setup_signals
33
+
32
34
  @pid = Process.pid
33
35
  Daemonizer.reopen_log_file
34
36
  Daemonizer.logger_context = "#{@pid}/#{@worker_id}"
35
-
37
+
36
38
  Daemonizer.logger.info "Log file reopened after fork"
37
39
  normal_exit = false
38
40
  begin
@@ -80,5 +82,17 @@ module Daemonizer
80
82
  Daemonizer.logger.error("Exception from kill: #{e} at #{e.backtrace.first}")
81
83
  end
82
84
  end
85
+
86
+ def send_signal(signal)
87
+ Process.kill(signal, @pid)
88
+ end
89
+
90
+ private
91
+
92
+ def setup_signals
93
+ trap('SIGHUP') do
94
+ Daemonizer.reopen_log_file
95
+ end
96
+ end
83
97
  end
84
98
  end
@@ -1,7 +1,7 @@
1
1
  module Daemonizer
2
2
  class WorkerPool
3
3
  MONITOR_VALUE = [:vm_size, :private_dirty_rss, :rss]
4
-
4
+
5
5
  attr_reader :name
6
6
  attr_reader :stats
7
7
 
@@ -12,7 +12,7 @@ module Daemonizer
12
12
  @workers = []
13
13
  @stats = ::SimpleStatistics::DataSet.new
14
14
  end
15
-
15
+
16
16
  def find_worker_by_name(name)
17
17
  @workers.detect do |w|
18
18
  w.process_name.to_s == name.to_s
@@ -29,7 +29,7 @@ module Daemonizer
29
29
  worker = Worker.new(name, @pm, i+1, &@worker_block)
30
30
  @workers << worker
31
31
  @stats.add_data(worker.process_name)
32
- Daemonizer.logger.info "Gathering data for #{worker.name}"
32
+ Daemonizer.logger.info "Gathering data for #{worker.name}"
33
33
  end
34
34
  rescue Exception => e
35
35
  Daemonizer.logger.info "Result - #{e.inspect}"
@@ -45,7 +45,7 @@ module Daemonizer
45
45
  @stats[worker_name][value].add_probe(p.send(value))
46
46
  end
47
47
  end
48
-
48
+
49
49
  @workers.each do |worker|
50
50
  unless worker.running? || worker.shutdown?
51
51
  Daemonizer.logger.warn "Worker #{worker.name} is not running. Restart!"
@@ -76,5 +76,11 @@ module Daemonizer
76
76
  worker.stop(force)
77
77
  end
78
78
  end
79
+
80
+ def send_signal_to_workers(signal)
81
+ @workers.each do |worker|
82
+ worker.send_signal(signal)
83
+ end
84
+ end
79
85
  end
80
86
  end
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ describe "with Daemonfile and daemonzier is in 'debug' mode" do
4
+
5
+ before :each do
6
+ @pid_files = simple_daemonfile(
7
+ :name => :test1,
8
+ :pid_file =>"#{tmp_dir}/test1.pid",
9
+ :on_prepare => "Daemonizer.logger.info \"test1: executed prepare\"",
10
+ :on_start => "Daemonizer.logger.info \"test1: executed start\"")
11
+ end
12
+
13
+ describe "with all pools" do
14
+
15
+ before(:each) do
16
+ daemonizer :debug
17
+ end
18
+
19
+ it "should return valid text" do
20
+ @out.should match(/You should supply pool_name to debug/)
21
+ end
22
+
23
+ it "should not return anything to stderr" do
24
+ @err.should == ''
25
+ end
26
+ end
27
+
28
+ describe "with specific pool" do
29
+
30
+ before(:each) do
31
+ daemonizer "debug test1"
32
+ end
33
+
34
+ it "should return valid text" do
35
+ @out.should match(/test1: executed prepare/)
36
+ @out.should match(/test1: executed start/)
37
+ end
38
+
39
+ it "should not return anything to stderr" do
40
+ @err.should == ''
41
+ end
42
+ end
43
+
44
+
45
+ end
@@ -0,0 +1,127 @@
1
+ require "spec_helper"
2
+
3
+ describe "with Daemonfile and daemonzier is not started " do
4
+
5
+ before :each do
6
+ @pid_files = simple_daemonfile({:name => :test1, :pid_file =>"#{tmp_dir}/test1.pid"}, {:name => :test2, :pid_file => "#{tmp_dir}/test2.pid"})
7
+ end
8
+
9
+ describe "on call 'stats'" do
10
+ before(:each) do
11
+ daemonizer :stats
12
+ end
13
+
14
+ it "should return valid text" do
15
+ @out.should match(/It seems like pool 'test1' is not running/)
16
+ @out.should match(/It seems like pool 'test2' is not running/)
17
+ end
18
+
19
+ it "should not return anything to stderr" do
20
+ @err.should == ''
21
+ end
22
+ end
23
+
24
+ describe "on call 'logrotate'" do
25
+ before(:each) do
26
+ daemonizer :logrotate
27
+ end
28
+
29
+ it "should return valid text" do
30
+ @out.should match(/test1: not started/)
31
+ @out.should match(/test2: not started/)
32
+ end
33
+
34
+ it "should not return anything to stderr" do
35
+ @err.should == ''
36
+ end
37
+ end
38
+
39
+ describe "on call 'start'" do
40
+ describe "with all pools" do
41
+ before(:each) do
42
+ daemonizer :start
43
+ end
44
+
45
+ after(:each) do
46
+ daemonizer :stop
47
+ end
48
+
49
+ it "should print info about starting 2 pools" do
50
+ @out.should match(/test1: Starting pool/)
51
+ @out.should match(/test1: successfully started/)
52
+ @out.should match(/test2: Starting pool/)
53
+ @out.should match(/test2: successfully started/)
54
+ end
55
+
56
+ it "should not return anything to stderr" do
57
+ @err.should == ''
58
+ end
59
+
60
+ it "should run daemonizer processes" do
61
+ daemonizer_runned?(@pid_files[0]).should be_true
62
+ daemonizer_runned?(@pid_files[1]).should be_true
63
+ end
64
+ end
65
+
66
+ describe "with specific pool" do
67
+ before(:each) do
68
+ daemonizer "start test1"
69
+ end
70
+
71
+ after(:each) do
72
+ daemonizer "stop test1"
73
+ end
74
+
75
+ it "should print info about starting 2 pools" do
76
+ @out.should match(/test1: Starting pool/)
77
+ @out.should match(/test1: successfully started/)
78
+ @out.should_not match(/test2: Starting pool/)
79
+ @out.should_not match(/test2: successfully started/)
80
+ end
81
+
82
+ it "should not return anything to stderr" do
83
+ @err.should == ''
84
+ end
85
+
86
+ it "should run daemonizer processes" do
87
+ daemonizer_runned?(@pid_files[0]).should be_true
88
+ daemonizer_runned?(@pid_files[1]).should be_false
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "on call 'stop'" do
94
+ describe "with all pools" do
95
+
96
+ before(:each) do
97
+ daemonizer :stop
98
+ end
99
+
100
+ it "should return valid text" do
101
+ @out.should match(/test1: No pid file or a stale pid file!/)
102
+ @out.should match(/test2: No pid file or a stale pid file!/)
103
+ end
104
+
105
+ it "should not return anything to stderr" do
106
+ @err.should == ''
107
+ end
108
+ end
109
+
110
+ describe "with specific pool" do
111
+
112
+ before(:each) do
113
+ daemonizer "stop test1"
114
+ end
115
+
116
+ it "should return valid text" do
117
+ @out.should match(/test1: No pid file or a stale pid file!/)
118
+ @out.should_not match(/test2: No pid file or a stale pid file!/)
119
+ end
120
+
121
+ it "should not return anything to stderr" do
122
+ @err.should == ''
123
+ end
124
+ end
125
+
126
+ end
127
+ end
@@ -0,0 +1,121 @@
1
+ require "spec_helper"
2
+
3
+ describe "with Daemonfile and daemonzier is already started " do
4
+
5
+ before :each do
6
+ @pid_files = simple_daemonfile({:name => :test1, :pid_file =>"#{tmp_dir}/test1.pid"}, {:name => :test2, :pid_file => "#{tmp_dir}/test2.pid"})
7
+ daemonizer "start"
8
+ end
9
+
10
+ after :each do
11
+ daemonizer "stop"
12
+ end
13
+
14
+ describe "on call 'stats'" do
15
+ before(:each) do
16
+ daemonizer :stats
17
+ end
18
+
19
+ it "should return valid text" do
20
+ @out.should match(/test1 processes/)
21
+ @out.should match(/test2 processes/)
22
+ end
23
+
24
+ it "should not return anything to stderr" do
25
+ @err.should == ''
26
+ end
27
+ end
28
+
29
+ describe "on call 'logrotate'" do
30
+ before(:each) do
31
+ daemonizer :logrotate
32
+ end
33
+
34
+ it "should return valid text" do
35
+ @out.should match(/test1: log file reopened/)
36
+ @out.should match(/test2: log file reopened/)
37
+ end
38
+
39
+ it "should not return anything to stderr" do
40
+ @err.should == ''
41
+ end
42
+ end
43
+
44
+ describe "on call 'start'" do
45
+ describe "with all pools" do
46
+ before(:each) do
47
+ daemonizer 'start'
48
+ end
49
+
50
+ it "should print info about starting 2 pools" do
51
+ @out.should match(/test1: Can't start, another process exists!/)
52
+ @out.should match(/test2: Can't start, another process exists!/)
53
+ end
54
+
55
+ it "should not return anything to stderr" do
56
+ @err.should == ''
57
+ end
58
+
59
+ it "should run daemonizer processes" do
60
+ daemonizer_runned?(@pid_files[0]).should be_true
61
+ daemonizer_runned?(@pid_files[1]).should be_true
62
+ end
63
+ end
64
+
65
+ describe "with specific pool" do
66
+ before(:each) do
67
+ daemonizer "start test1"
68
+ end
69
+
70
+ it "should print info about starting 2 pools" do
71
+ @out.should match(/test1: Can't start, another process exists!/)
72
+ @out.should_not match(/test2/)
73
+ end
74
+
75
+ it "should not return anything to stderr" do
76
+ @err.should == ''
77
+ end
78
+
79
+ it "should run daemonizer processes" do
80
+ daemonizer_runned?(@pid_files[0]).should be_true
81
+ daemonizer_runned?(@pid_files[1]).should be_true
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ describe "on call 'stop'" do
88
+ describe "with all pools" do
89
+
90
+ before(:each) do
91
+ daemonizer "stop"
92
+ end
93
+
94
+ it "should return valid text" do
95
+ @out.should match(/test1: Killing the process/)
96
+ @out.should match(/test2: Killing the process/)
97
+ end
98
+
99
+ it "should not return anything to stderr" do
100
+ @err.should == ''
101
+ end
102
+ end
103
+
104
+ describe "with specific pool" do
105
+
106
+ before(:each) do
107
+ daemonizer "stop test1"
108
+ end
109
+
110
+ it "should return valid text" do
111
+ @out.should match(/test1: Killing the process/)
112
+ @out.should_not match(/test2: Killing the process/)
113
+ end
114
+
115
+ it "should not return anything to stderr" do
116
+ @err.should == ''
117
+ end
118
+ end
119
+
120
+ end
121
+ end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ describe "daemonzier after start" do
4
+
5
+ before :each do
6
+ @pid_files = simple_daemonfile(
7
+ :name => :test1,
8
+ :pid_file =>"#{tmp_dir}/test1.pid",
9
+ :on_start => "loop { sleep 1 }",
10
+ :workers => 3,
11
+ :poll_period => 1)
12
+ daemonizer :start
13
+ sleep 8
14
+ end
15
+
16
+ after :each do
17
+ daemonizer :stop
18
+ end
19
+
20
+ it "should create 3 forks" do
21
+ children_count(pid(@pid_files[0])).should == 3
22
+ end
23
+
24
+ describe "after one worker died" do
25
+ before :each do
26
+ Process.kill("KILL", children_pids(pid(@pid_files[0])).first.to_i)
27
+ sleep 5
28
+ end
29
+
30
+ it "should restore it" do
31
+ children_count(pid(@pid_files[0])).should == 3
32
+ end
33
+ end
34
+
35
+ end