light-daemon 0.9.0 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/light_daemon.rb +103 -50
  2. metadata +5 -5
@@ -1,49 +1,98 @@
1
1
  module LightDaemon
2
2
  class Daemon
3
- def initialize(obj, options={})
4
- @obj = obj
5
- @options = options
6
- log("before daemonize")
3
+ DEFAULT_PID_FILE = "/tmp/light_daemon.pid"
4
+
5
+ class << self
6
+ def start(obj, options={})
7
+ @options = self.make_options(options)
8
+ @pid_file = @options[:pid_file]
9
+ if self.get_pid
10
+ raise "The pid file \"#{@pid_file}\" existed already. You need to stop the daemon first."
11
+ end
12
+ self.new(obj, @options).start
13
+ end
14
+
15
+ def stop(pid_file=DEFAULT_PID_FILE)
16
+ @pid_file = pid_file
17
+ if(pid = self.get_pid)
18
+ begin
19
+ Process.kill("TERM", pid)
20
+ rescue Errno::ESRCH
21
+ # no such process. do nothing
22
+ end
23
+ self.clear_pid
24
+ end
25
+ end
26
+
27
+ def get_pid
28
+ return nil unless File.exist?(@pid_file)
29
+ begin
30
+ File.open(@pid_file) {|f| f.read}.to_i
31
+ rescue
32
+ nil
33
+ end
34
+ end
35
+
36
+ def set_pid(pid)
37
+ File.open(@pid_file, 'w') {|f| f.write(pid.to_s)}
38
+ end
39
+
40
+ def clear_pid
41
+ File.unlink(@pid_file)
42
+ end
43
+
44
+ def make_options(options)
45
+ options[:children] ||= 1
46
+ options[:monitor_cycle] ||= 10 # seconds
47
+ options[:pid_file] ||= DEFAULT_PID_FILE
48
+ options
49
+ end
50
+
51
+ # for debugging
52
+ # def log(msg)
53
+ # File.open("/tmp/yi.txt", "a") do |f|
54
+ # f.puts msg
55
+ # end
56
+ # end
57
+ end
58
+
59
+ def initialize(obj, options)
7
60
  daemonize
8
- log("after daemonize")
61
+ self.class.set_pid(Process.pid)
62
+
63
+ @options = options
64
+ @obj = obj
9
65
  @processes = []
66
+ @is_child = false
10
67
  signal_handling
11
68
  end
12
69
 
13
- def self.start(obj, options={})
14
- self.new(obj, options).start
15
- end
16
-
17
70
  def signal_handling
18
- $_simple_daemon_running = true
71
+ $keep_running = true
19
72
  Signal.trap "TERM" do
20
- log("Daemon received TERM !!!!!!!!!!!!!!!!!")
21
- @processes.each do |pid|
22
- Process.kill("TERM", pid)
23
- end
24
-
25
- sleep(3)
26
- 3.times do
27
- @processes.size.times do
28
- pid = @processes.shift
29
- if process_alive?(pid)
30
- @processes << pid
31
- sleep(3)
32
- end
33
- end
34
- end
35
- @processes.each do |pid|
36
- Process.kill(9, pid)
73
+ unless @is_child
74
+ @processes.each do |pid|
75
+ Process.kill("TERM", pid)
76
+ end
77
+
78
+ sleep(3)
79
+ options[:children].times do
80
+ @processes.size.times do
81
+ pid = @processes.shift
82
+ if process_alive?(pid)
83
+ @processes << pid
84
+ sleep(3)
85
+ end
86
+ end
87
+ end
88
+ @processes.each do |pid|
89
+ Process.kill(9, pid)
90
+ end
37
91
  end
38
- $_simple_daemon_running = false
92
+ $keep_running = false
39
93
  end
40
94
  end
41
95
 
42
- def log(msg)
43
- File.open("/tmp/yi.txt", "a") do |f|
44
- f.puts msg
45
- end
46
- end
47
96
 
48
97
  def process_alive?(pid)
49
98
  return false unless pid
@@ -57,33 +106,45 @@ module LightDaemon
57
106
  end
58
107
  end
59
108
 
60
-
61
109
  def start
62
- 5.times do
110
+ @options[:children].times do
63
111
  if pid = fork
64
112
  @processes << pid
65
113
  Process.detach(pid)
66
114
  else
67
- return @obj.send(:call)
115
+ set_child
116
+ while($keep_running)
117
+ break unless @obj.send(:call)
118
+ end
119
+ return
68
120
  end
69
121
  end
70
122
 
71
- while($_simple_daemon_running)
72
- sleep(5)
123
+ while($keep_running)
124
+ sleep(@options[:monitor_cycle])
125
+
73
126
  @processes.each_with_index do |pid, index|
74
127
  unless process_alive?(pid)
75
128
  if pid = fork
76
129
  @processes[index] = pid
77
130
  Process.detach(pid)
131
+ sleep(2)
78
132
  else
79
- return @obj.send(:call)
133
+ set_child
134
+ while($keep_running)
135
+ break unless @obj.send(:call)
136
+ end
137
+ return
80
138
  end
139
+ else
81
140
  end
82
141
  sleep(1)
83
142
  end
84
143
  end
144
+ self.class.clear_pid(@options[:pid_file])
85
145
  end
86
146
 
147
+ # some code in this method is learned from gem daemons
87
148
  def daemonize
88
149
  fork && exit
89
150
  unless Process.setsid
@@ -93,22 +154,14 @@ module LightDaemon
93
154
  trap 'SIGHUP', 'IGNORE'
94
155
  exit if fork
95
156
 
96
- ObjectSpace.each_object(IO) do |io|
97
- unless [STDIN, STDOUT, STDERR].include?(io)
98
- begin
99
- unless io.closed?
100
- io.close
101
- end
102
- rescue ::Exception
103
- end
104
- end
105
- end
106
-
107
157
  begin; STDIN.reopen "/dev/null"; rescue ::Exception; end
108
158
  begin; STDOUT.reopen "/dev/null"; rescue ::Exception; end
109
159
  begin; STDERR.reopen STDOUT; rescue ::Exception; end
110
160
  STDERR.sync = true
161
+ end
111
162
 
163
+ def set_child
164
+ @is_child = true
112
165
  end
113
166
  end
114
167
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: light-daemon
3
3
  version: !ruby/object:Gem::Version
4
- hash: 59
4
+ hash: 49
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 0
10
- version: 0.9.0
9
+ - 5
10
+ version: 0.9.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Yi Zhang
@@ -15,11 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-03-08 00:00:00 -08:00
18
+ date: 2012-03-10 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
22
- description: A simple and light daemon
22
+ description: A very simple and light ruby daemon API
23
23
  email: yzhang.wa@gmail.com
24
24
  executables: []
25
25