daemons 1.1.9 → 1.2.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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +1 -1
  3. data/README.md +206 -0
  4. data/Releases +17 -0
  5. data/examples/call/call.rb +13 -16
  6. data/examples/call/call_monitor.rb +13 -17
  7. data/examples/daemonize/daemonize.rb +4 -8
  8. data/examples/run/ctrl_crash.rb +0 -1
  9. data/examples/run/ctrl_custom_logfiles.rb +18 -0
  10. data/examples/run/ctrl_exec.rb +0 -1
  11. data/examples/run/ctrl_exit.rb +0 -1
  12. data/examples/run/ctrl_keep_pid_files.rb +1 -3
  13. data/examples/run/ctrl_monitor.rb +0 -1
  14. data/examples/run/ctrl_monitor_multiple.rb +17 -0
  15. data/examples/run/ctrl_multiple.rb +0 -1
  16. data/examples/run/ctrl_ontop.rb +0 -1
  17. data/examples/run/ctrl_optionparser.rb +4 -6
  18. data/examples/run/ctrl_proc.rb +8 -9
  19. data/examples/run/ctrl_proc_multiple.rb +4 -6
  20. data/examples/run/ctrl_proc_rand.rb +2 -4
  21. data/examples/run/ctrl_proc_simple.rb +0 -1
  22. data/examples/run/myserver.rb +0 -1
  23. data/examples/run/myserver_crashing.rb +5 -5
  24. data/examples/run/myserver_exiting.rb +2 -2
  25. data/examples/run/myserver_hanging.rb +4 -5
  26. data/examples/run/myserver_slowstop.rb +5 -6
  27. data/lib/daemons.rb +66 -68
  28. data/lib/daemons/application.rb +171 -188
  29. data/lib/daemons/application_group.rb +99 -92
  30. data/lib/daemons/change_privilege.rb +3 -3
  31. data/lib/daemons/cmdline.rb +43 -54
  32. data/lib/daemons/controller.rb +36 -53
  33. data/lib/daemons/daemonize.rb +54 -64
  34. data/lib/daemons/etc_extension.rb +3 -2
  35. data/lib/daemons/exceptions.rb +10 -11
  36. data/lib/daemons/monitor.rb +60 -62
  37. data/lib/daemons/pid.rb +24 -56
  38. data/lib/daemons/pidfile.rb +38 -40
  39. data/lib/daemons/pidmem.rb +5 -9
  40. data/lib/daemons/version.rb +3 -0
  41. metadata +45 -45
  42. data/README +0 -214
  43. data/Rakefile +0 -90
  44. data/TODO +0 -2
  45. data/setup.rb +0 -1360
@@ -8,7 +8,6 @@ end
8
8
 
9
9
  require 'daemons'
10
10
 
11
-
12
11
  options = {
13
12
  :monitor => true
14
13
  }
@@ -0,0 +1,17 @@
1
+ lib_dir = File.expand_path(File.join(File.dirname(__FILE__), '../../lib'))
2
+
3
+ if File.exist?(File.join(lib_dir, 'daemons.rb'))
4
+ $LOAD_PATH.unshift lib_dir
5
+ else
6
+ begin; require 'rubygems'; rescue ::Exception; end
7
+ end
8
+
9
+ require 'daemons'
10
+
11
+ options = {
12
+ :multiple => true,
13
+ :monitor => true,
14
+ :log_output => true,
15
+ }
16
+
17
+ Daemons.run(File.join(File.dirname(__FILE__), 'myserver_crashing.rb'), options)
@@ -8,7 +8,6 @@ end
8
8
 
9
9
  require 'daemons'
10
10
 
11
-
12
11
  options = {
13
12
  :multiple => true
14
13
  }
@@ -8,7 +8,6 @@ end
8
8
 
9
9
  require 'daemons'
10
10
 
11
-
12
11
  options = {
13
12
  :ontop => true
14
13
  }
@@ -11,7 +11,6 @@ require 'optparse'
11
11
  require 'logger'
12
12
  require 'ostruct'
13
13
 
14
-
15
14
  class MyApp < Logger::Application
16
15
  def initialize(args)
17
16
  super(self.class)
@@ -19,15 +18,15 @@ class MyApp < Logger::Application
19
18
  opts = OptionParser.new do |opts|
20
19
  opts.banner = 'Usage: myapp [options]'
21
20
  opts.separator ''
22
- opts.on('-N','--no-daemonize',"Don't run as a daemon") do
21
+ opts.on('-N', '--no-daemonize', "Don't run as a daemon") do
23
22
  @options.daemonize = false
24
23
  end
25
24
  end
26
25
  @args = opts.parse!(args)
27
26
  end
28
-
27
+
29
28
  def run
30
- Daemons.run_proc('myapp',{:ARGV => @args, :ontop => !@options.daemonize}) do
29
+ Daemons.run_proc('myapp', :ARGV => @args, :ontop => !@options.daemonize) do
31
30
  puts "@options.daemonize: #{@options.daemonize}"
32
31
  STDOUT.sync = true
33
32
  loop do
@@ -38,6 +37,5 @@ class MyApp < Logger::Application
38
37
  end
39
38
  end
40
39
 
41
-
42
40
  myapp = MyApp.new(ARGV)
43
- myapp.run
41
+ myapp.run
@@ -8,18 +8,17 @@ end
8
8
 
9
9
  require 'daemons'
10
10
 
11
-
12
11
  options = {
13
- :multiple => false,
14
- :ontop => false,
15
- :backtrace => true,
16
- :log_output => true,
17
- :monitor => true
18
- }
19
-
12
+ :multiple => false,
13
+ :ontop => false,
14
+ :backtrace => true,
15
+ :log_output => true,
16
+ :monitor => true
17
+ }
18
+
20
19
  Daemons.run_proc('ctrl_proc.rb', options) do
21
20
  loop do
22
21
  puts 'ping from proc!'
23
22
  sleep(3)
24
23
  end
25
- end
24
+ end
@@ -8,15 +8,13 @@ end
8
8
 
9
9
  require 'daemons'
10
10
 
11
-
12
11
  options = {
13
12
  :log_output => true,
14
- :multiple => true,
13
+ :multiple => true,
15
14
  }
16
15
 
17
-
18
16
  Daemons.run_proc('ctrl_proc_multiple.rb', options) do
19
- puts "hello"
17
+ puts 'hello'
20
18
  sleep(5)
21
- puts "done"
22
- end
19
+ puts 'done'
20
+ end
@@ -6,10 +6,8 @@ else
6
6
  begin; require 'rubygems'; rescue ::Exception; end
7
7
  end
8
8
 
9
-
10
9
  require 'daemons'
11
10
 
12
-
13
11
  Daemons.run_proc('myscript') do
14
12
  loop do
15
13
  file = File.open('/tmp/myscript.log', 'a')
@@ -17,7 +15,7 @@ Daemons.run_proc('myscript') do
17
15
  # file.write(Random.new.rand) # works without seeding
18
16
  # file.write(rand) # also works, but this is Kernel.rand() so its different
19
17
  file.write("\n")
20
- file.close()
18
+ file.close
21
19
  sleep 2
22
20
  end
23
- end
21
+ end
@@ -8,7 +8,6 @@ end
8
8
 
9
9
  require 'daemons'
10
10
 
11
-
12
11
  Daemons.run_proc('ctrl_proc_simple.rb') do
13
12
  loop do
14
13
  puts 'ping from proc!'
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
-
4
3
  # This is myserver.rb, an example server that is to be controlled by daemons
5
4
  # and that does nothing really useful at the moment.
6
5
  #
@@ -5,10 +5,10 @@
5
5
 
6
6
  loop do
7
7
  puts 'ping from myserver.rb!'
8
- puts 'this example server will crash in 3 seconds...'
9
-
10
- sleep(3)
11
-
8
+ puts 'this example server will crash in 10 seconds...'
9
+
10
+ sleep(10)
11
+
12
12
  puts 'CRASH!'
13
- raise 'CRASH!'
13
+ fail 'CRASH!'
14
14
  end
@@ -1,8 +1,8 @@
1
1
  loop do
2
2
  puts 'ping from myserver.rb!'
3
3
  puts 'this example server will exit in 3 seconds...'
4
-
4
+
5
5
  sleep(3)
6
-
6
+
7
7
  Process.exit
8
8
  end
@@ -1,19 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
-
4
3
  # This is myserver.rb, an example server that is to be controlled by daemons
5
4
  # and that does nothing really useful at the moment.
6
5
  #
7
6
  # Don't run this script by yourself, it can be controlled by the ctrl*.rb scripts.
8
7
 
9
- trap('TERM') {
10
- puts "received TERM"
11
-
8
+ trap('TERM') do
9
+ puts 'received TERM'
10
+
12
11
  loop do
13
12
  puts 'hanging!'
14
13
  sleep(3)
15
14
  end
16
- }
15
+ end
17
16
 
18
17
  loop do
19
18
  puts 'ping from myserver.rb!'
@@ -1,19 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
-
4
3
  # This is myserver_slowstop.rb, an example server that is to be controlled by daemons
5
4
  # and that does nothing really useful at the moment.
6
5
  #
7
6
  # Don't run this script by yourself, it can be controlled by the ctrl*.rb scripts.
8
7
 
9
- trap('TERM') {
10
- puts "received TERM"
11
-
8
+ trap('TERM') do
9
+ puts 'received TERM'
10
+
12
11
  # simulate the slow stopping
13
12
  sleep(10)
14
-
13
+
15
14
  exit
16
- }
15
+ end
17
16
 
18
17
  loop do
19
18
  puts 'ping from myserver.rb!'
data/lib/daemons.rb CHANGED
@@ -1,19 +1,16 @@
1
1
  require 'optparse'
2
2
  require 'optparse/time'
3
3
 
4
-
5
- require 'daemons/pidfile'
4
+ require 'daemons/version'
5
+ require 'daemons/pidfile'
6
6
  require 'daemons/cmdline'
7
7
  require 'daemons/exceptions'
8
8
  require 'daemons/monitor'
9
9
 
10
-
11
10
  require 'daemons/application'
12
11
  require 'daemons/application_group'
13
12
  require 'daemons/controller'
14
13
 
15
- require 'timeout'
16
-
17
14
  # All functions and classes that Daemons provides reside in this module.
18
15
  #
19
16
  # Daemons is normally invoked by one of the following four ways:
@@ -25,7 +22,7 @@ require 'timeout'
25
22
  # to do anything useful.
26
23
  #
27
24
  # 2. <tt>Daemons.run_proc(app_name, options) { (...) }</tt>:
28
- # This is used in wrapper-scripts that are supposed to control a proc.
25
+ # This is used in wrapper-scripts that are supposed to control a proc.
29
26
  # Control is completely passed to the daemons library.
30
27
  # Such wrapper scripts need to be invoked with command line options like 'start' or 'stop'
31
28
  # to do anything useful.
@@ -65,12 +62,8 @@ require 'timeout'
65
62
  # called <i>PidFiles</i> are stored.
66
63
  #
67
64
  module Daemons
68
-
69
- VERSION = "1.1.9"
70
-
71
65
  require 'daemons/daemonize'
72
-
73
-
66
+
74
67
  # Passes control to Daemons.
75
68
  # This is used in wrapper-scripts that are supposed to control other ruby scripts or
76
69
  # external applications. Control is completely passed to the daemons library.
@@ -82,7 +75,7 @@ module Daemons
82
75
  # Also note that Daemons cannot detect the directory in which the controlling
83
76
  # script resides, so this has to be either an absolute path or you have to run
84
77
  # the controlling script from the appropriate directory. Your script name should not
85
- # end with _monitor because that name is reserved for a monitor process which is
78
+ # end with _monitor because that name is reserved for a monitor process which is
86
79
  # there to restart your daemon if it crashes.
87
80
  #
88
81
  # +options+:: A hash that may contain one or more of the options listed below
@@ -97,44 +90,48 @@ module Daemons
97
90
  # These are assumed to be separated by an array element '--', .e.g.
98
91
  # ['start', 'f', '--', 'param1_for_script', 'param2_for_script'].
99
92
  # If not given, ARGV (the parameters given to the Ruby process) will be used.
100
- # <tt>:dir_mode</tt>:: Either <tt>:script</tt> (the directory for writing the pid files to
93
+ # <tt>:dir_mode</tt>:: Either <tt>:script</tt> (the directory for writing the pid files to
101
94
  # given by <tt>:dir</tt> is interpreted relative
102
- # to the script location given by +script+, the default) or <tt>:normal</tt> (the directory given by
103
- # <tt>:dir</tt> is interpreted as a (absolute or relative) path) or <tt>:system</tt>
95
+ # to the script location given by +script+, the default) or <tt>:normal</tt> (the directory given by
96
+ # <tt>:dir</tt> is interpreted as a (absolute or relative) path) or <tt>:system</tt>
104
97
  # (<tt>/var/run</tt> is used as the pid file directory)
105
98
  #
106
99
  # <tt>:dir</tt>:: Used in combination with <tt>:dir_mode</tt> (description above)
107
100
  # <tt>:multiple</tt>:: Specifies whether multiple instances of the same script are allowed to run at the
108
101
  # same time
109
- # <tt>:ontop</tt>:: When given (i.e. set to true), stay on top, i.e. do not daemonize the application
102
+ # <tt>:ontop</tt>:: When given (i.e. set to true), stay on top, i.e. do not daemonize the application
110
103
  # (but the pid-file and other things are written as usual)
111
104
  # <tt>:mode</tt>:: <tt>:load</tt> Load the script with <tt>Kernel.load</tt>;
112
105
  # note that :stop_proc only works for the :load (and :proc) mode.
113
106
  # <tt>:exec</tt> Execute the script file with <tt>Kernel.exec</tt>
114
- # <tt>:backtrace</tt>:: Write a backtrace of the last exceptions to the file '[app_name].log' in the
107
+ # <tt>:backtrace</tt>:: Write a backtrace of the last exceptions to the file '[app_name].log' in the
115
108
  # pid-file directory if the application exits due to an uncaught exception
116
109
  # <tt>:monitor</tt>:: Monitor the programs and restart crashed instances
117
110
  # <tt>:log_dir</tt>:: A specific directory to put the log files into (when not given, resort to the default
118
111
  # location as derived from the :dir_mode and :dir options
119
- # <tt>:log_output</tt>:: When given (i.e. set to true), redirect both STDOUT and STDERR to a logfile named '[app_name].output' in the pid-file directory
112
+ # <tt>:logfilename</tt>:: Specifiy a custom log file name
113
+ # <tt>:log_output</tt>:: When given (i.e. set to true), redirect both STDOUT and STDERR to a logfile named '[app_name].output' (or as given in :output_logfilename) in the pid-file directory
114
+ # <tt>:output_logfilename</tt>:: Specifiy a custom output redirection file name
120
115
  # <tt>:keep_pid_files</tt>:: When given do not delete lingering pid-files (files for which the process is no longer running).
121
116
  # <tt>:hard_exit</tt>:: When given use exit! to end a daemons instead of exit (this will for example
122
117
  # not call at_exit handlers).
123
118
  # <tt>:stop_proc</tt>:: A proc that will be called when the daemonized process receives a request to stop (works only for :load and :proc mode)
124
119
  #
125
120
  # -----
126
- #
121
+ #
127
122
  # === Example:
128
123
  # options = {
129
- # :app_name => "my_app",
130
- # :ARGV => ['start', '-f', '--', 'param_for_myscript']
131
- # :dir_mode => :script,
132
- # :dir => 'pids',
133
- # :multiple => true,
134
- # :ontop => true,
135
- # :mode => :exec,
136
- # :backtrace => true,
137
- # :monitor => true
124
+ # :app_name => "my_app",
125
+ # :ARGV => ['start', '-f', '--', 'param_for_myscript']
126
+ # :dir_mode => :script,
127
+ # :dir => 'pids',
128
+ # :multiple => true,
129
+ # :ontop => true,
130
+ # :mode => :exec,
131
+ # :backtrace => true,
132
+ # :monitor => true,
133
+ # :logfilename => 'custom_logfile.log',
134
+ # :output_logfilename => 'custom_outputfile.txt'
138
135
  # }
139
136
  #
140
137
  # Daemons.run(File.join(File.dirname(__FILE__), 'myscript.rb'), options)
@@ -142,17 +139,16 @@ module Daemons
142
139
  def run(script, options = {})
143
140
  options[:script] = script
144
141
  @controller = Controller.new(options, options[:ARGV] || ARGV)
145
-
146
- @controller.catch_exceptions {
142
+
143
+ @controller.catch_exceptions do
147
144
  @controller.run
148
- }
149
-
145
+ end
146
+
150
147
  # I don't think anybody will ever use @group, as this location should not be reached under non-error conditions
151
148
  @group = @controller.group
152
149
  end
153
150
  module_function :run
154
-
155
-
151
+
156
152
  # Passes control to Daemons.
157
153
  # This function does the same as Daemons.run except that not a script but a proc
158
154
  # will be run as a daemon while this script provides command line options like 'start' or 'stop'
@@ -162,13 +158,13 @@ module Daemons
162
158
  # used to contruct the name of the pid files
163
159
  # and log files. Defaults to the basename of
164
160
  # the script.
165
- #
161
+ #
166
162
  # +options+:: A hash that may contain one or more of the options listed in the documentation for Daemons.run
167
163
  #
168
164
  # A block must be given to this function. The block will be used as the :proc entry in the options hash.
169
165
  #
170
166
  # -----
171
- #
167
+ #
172
168
  # === Example:
173
169
  #
174
170
  # Daemons.run_proc('myproc.rb') do
@@ -184,25 +180,24 @@ module Daemons
184
180
  options[:app_name] = app_name
185
181
  options[:mode] = :proc
186
182
  options[:proc] = block
187
-
183
+
188
184
  # we do not have a script location so the the :script :dir_mode cannot be used, change it to :normal
189
185
  if [nil, :script].include? options[:dir_mode]
190
186
  options[:dir_mode] = :normal
191
187
  options[:dir] ||= File.expand_path('.')
192
188
  end
193
-
189
+
194
190
  @controller = Controller.new(options, options[:ARGV] || ARGV)
195
-
196
- @controller.catch_exceptions {
191
+
192
+ @controller.catch_exceptions do
197
193
  @controller.run
198
- }
199
-
194
+ end
195
+
200
196
  # I don't think anybody will ever use @group, as this location should not be reached under non-error conditions
201
197
  @group = @controller.group
202
198
  end
203
199
  module_function :run_proc
204
-
205
-
200
+
206
201
  # Execute the block in a new daemon. <tt>Daemons.call</tt> will return immediately
207
202
  # after spawning the daemon with the new Application object as a return value.
208
203
  #
@@ -215,11 +210,11 @@ module Daemons
215
210
  # === Options:
216
211
  # <tt>:multiple</tt>:: Specifies whether multiple instances of the same script are allowed to run at the
217
212
  # same time
218
- # <tt>:ontop</tt>:: When given, stay on top, i.e. do not daemonize the application
219
- # <tt>:backtrace</tt>:: Write a backtrace of the last exceptions to the file '[app_name].log' in the
213
+ # <tt>:ontop</tt>:: When given, stay on top, i.e. do not daemonize the application
214
+ # <tt>:backtrace</tt>:: Write a backtrace of the last exceptions to the file '[app_name].log' in the
220
215
  # pid-file directory if the application exits due to an uncaught exception
221
216
  # -----
222
- #
217
+ #
223
218
  # === Example:
224
219
  # options = {
225
220
  # :app_name => "myproc",
@@ -238,40 +233,39 @@ module Daemons
238
233
  #
239
234
  def call(options = {}, &block)
240
235
  unless block_given?
241
- raise "Daemons.call: no block given"
236
+ fail 'Daemons.call: no block given'
242
237
  end
243
-
238
+
244
239
  options[:proc] = block
245
240
  options[:mode] = :proc
246
-
241
+
247
242
  options[:app_name] ||= 'proc'
248
-
243
+
249
244
  @group ||= ApplicationGroup.new(options[:app_name], options)
250
-
245
+
251
246
  new_app = @group.new_application(options)
252
247
  new_app.start
253
248
 
254
- return new_app
249
+ new_app
255
250
  end
256
251
  module_function :call
257
-
258
-
252
+
259
253
  # Daemonize the currently runnig process, i.e. the calling process will become a daemon.
260
254
  #
261
255
  # +options+:: A hash that may contain one or more of the options listed below
262
256
  #
263
257
  # === Options:
264
- # <tt>:ontop</tt>:: When given, stay on top, i.e. do not daemonize the application
265
- # <tt>:backtrace</tt>:: Write a backtrace of the last exceptions to the file '[app_name].log' in the
258
+ # <tt>:ontop</tt>:: When given, stay on top, i.e. do not daemonize the application
259
+ # <tt>:backtrace</tt>:: Write a backtrace of the last exceptions to the file '[app_name].log' in the
266
260
  # pid-file directory if the application exits due to an uncaught exception
267
261
  # <tt>:app_name</tt>:: The name of the application. This will be
268
262
  # used to contruct the name of the pid files
269
263
  # and log files. Defaults to the basename of
270
264
  # the script.
271
- # <tt>:dir_mode</tt>:: Either <tt>:script</tt> (the directory for writing files to
265
+ # <tt>:dir_mode</tt>:: Either <tt>:script</tt> (the directory for writing files to
272
266
  # given by <tt>:dir</tt> is interpreted relative
273
- # to the script location given by +script+, the default) or <tt>:normal</tt> (the directory given by
274
- # <tt>:dir</tt> is interpreted as a (absolute or relative) path) or <tt>:system</tt>
267
+ # to the script location given by +script+, the default) or <tt>:normal</tt> (the directory given by
268
+ # <tt>:dir</tt> is interpreted as a (absolute or relative) path) or <tt>:system</tt>
275
269
  # (<tt>/var/run</tt> is used as the file directory)
276
270
  #
277
271
  # <tt>:dir</tt>:: Used in combination with <tt>:dir_mode</tt> (description above)
@@ -279,7 +273,7 @@ module Daemons
279
273
  # location as derived from the :dir_mode and :dir options
280
274
  # <tt>:log_output</tt>:: When given (i.e. set to true), redirect both STDOUT and STDERR to a logfile named '[app_name].output' in the pid-file directory
281
275
  # -----
282
- #
276
+ #
283
277
  # === Example:
284
278
  # options = {
285
279
  # :backtrace => true,
@@ -298,18 +292,22 @@ module Daemons
298
292
  #
299
293
  def daemonize(options = {})
300
294
  options[:script] ||= File.basename(__FILE__)
301
-
295
+
302
296
  @group ||= ApplicationGroup.new(options[:app_name] || options[:script], options)
303
-
297
+
304
298
  @group.new_application(:mode => :none).start
305
299
  end
306
300
  module_function :daemonize
307
-
301
+
308
302
  # Return the internal ApplicationGroup instance.
309
- def group; @group; end
303
+ def group
304
+ @group
305
+ end
310
306
  module_function :group
311
-
307
+
312
308
  # Return the internal Controller instance.
313
- def controller; @controller; end
309
+ def controller
310
+ @controller
311
+ end
314
312
  module_function :controller
315
- end
313
+ end