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
@@ -1,65 +1,63 @@
1
1
 
2
2
  module Daemons
3
3
  class ApplicationGroup
4
-
5
4
  attr_reader :app_name
6
5
  attr_reader :script
7
-
6
+
8
7
  attr_reader :monitor
9
-
10
- #attr_reader :controller
11
-
8
+
9
+ # attr_reader :controller
10
+
12
11
  attr_reader :options
13
-
12
+
14
13
  attr_reader :applications
15
-
14
+
16
15
  attr_accessor :controller_argv
17
16
  attr_accessor :app_argv
18
-
17
+
19
18
  attr_accessor :dir_mode
20
19
  attr_accessor :dir
21
-
20
+
22
21
  # true if the application is supposed to run in multiple instances
23
22
  attr_reader :multiple
24
-
25
-
23
+
26
24
  def initialize(app_name, options = {})
27
25
  @app_name = app_name
28
26
  @options = options
29
-
27
+
30
28
  if options[:script]
31
29
  @script = File.expand_path(options[:script])
32
30
  end
33
-
34
- #@controller = controller
31
+
32
+ # @controller = controller
35
33
  @monitor = nil
36
-
37
- #options = controller.options
38
-
34
+
35
+ # options = controller.options
36
+
39
37
  @multiple = options[:multiple] || false
40
-
38
+
41
39
  @dir_mode = options[:dir_mode] || :script
42
40
  @dir = options[:dir] || ''
43
-
41
+
44
42
  @keep_pid_files = options[:keep_pid_files] || false
45
43
  @no_pidfiles = options[:no_pidfiles] || false
46
-
47
- #@applications = find_applications(pidfile_dir())
44
+
45
+ # @applications = find_applications(pidfile_dir())
48
46
  @applications = []
49
47
  end
50
-
48
+
51
49
  # Setup the application group.
52
50
  # Currently this functions calls <tt>find_applications</tt> which finds
53
51
  # all running instances of the application and populates the application array.
54
52
  #
55
53
  def setup
56
- @applications = find_applications(pidfile_dir())
54
+ @applications = find_applications(pidfile_dir)
57
55
  end
58
-
56
+
59
57
  def pidfile_dir
60
58
  PidFile.dir(@dir_mode, @dir, script)
61
- end
62
-
59
+ end
60
+
63
61
  def find_applications(dir)
64
62
  if @no_pidfiles
65
63
  return find_applications_by_app_name(app_name)
@@ -67,128 +65,137 @@ module Daemons
67
65
  return find_applications_by_pidfiles(dir)
68
66
  end
69
67
  end
70
-
68
+
71
69
  # TODO: identifiy the monitor process
72
70
  def find_applications_by_app_name(app_name)
73
71
  pids = []
74
-
72
+
75
73
  begin
76
- x = `ps auxw | grep -v grep | awk '{print $2, $11, $12}' | grep #{app_name}`
77
- if x && x.chomp!
78
- processes = x.split(/\n/).compact
79
- processes = processes.delete_if do |p|
80
- pid, name, add = p.split(/\s/)
81
- # We want to make sure that the first part of the process name matches
82
- # so that app_name matches app_name_22
83
-
84
- app_name != name[0..(app_name.length - 1)] and not add.include?(app_name)
74
+ x = `ps auxw | grep -v grep | awk '{print $2, $11, $12}' | grep #{app_name}`
75
+ if x && x.chomp!
76
+ processes = x.split(/\n/).compact
77
+ processes = processes.delete_if do |p|
78
+ pid, name, add = p.split(/\s/)
79
+ # We want to make sure that the first part of the process name matches
80
+ # so that app_name matches app_name_22
81
+
82
+ app_name != name[0..(app_name.length - 1)] and not add.include?(app_name)
83
+ end
84
+ pids = processes.map { |p| p.split(/\s/)[0].to_i }
85
85
  end
86
- pids = processes.map {|p| p.split(/\s/)[0].to_i}
86
+ rescue ::Exception
87
87
  end
88
- rescue ::Exception
89
- end
90
-
91
- return pids.map {|f|
88
+
89
+ pids.map do |f|
92
90
  app = Application.new(self, {}, PidMem.existing(f))
93
91
  setup_app(app)
94
92
  app
95
- }
93
+ end
96
94
  end
97
-
95
+
98
96
  def find_applications_by_pidfiles(dir)
99
- pid_files = PidFile.find_files(dir, app_name, ! @keep_pid_files)
100
-
101
- #pp pid_files
102
-
103
97
  @monitor = Monitor.find(dir, app_name + '_monitor')
104
-
105
- pid_files.reject! {|f| f =~ /_monitor.pid$/}
106
-
107
- return pid_files.map {|f|
98
+
99
+ pid_files = PidFile.find_files(dir, app_name, ! @keep_pid_files)
100
+ pid_files.map do |f|
108
101
  app = Application.new(self, {}, PidFile.existing(f))
109
102
  setup_app(app)
110
103
  app
111
- }
104
+ end
112
105
  end
113
-
106
+
114
107
  def new_application(add_options = {})
115
- if @applications.size > 0 and not @multiple
108
+ if @applications.size > 0 && !@multiple
116
109
  if options[:force]
117
- @applications.delete_if {|a|
110
+ @applications.delete_if do |a|
118
111
  unless a.running?
119
112
  a.zap
120
113
  true
121
114
  end
122
- }
115
+ end
123
116
  end
124
-
125
- raise RuntimeException.new('there is already one or more instance(s) of the program running') unless @applications.empty?
117
+
118
+ fail RuntimeException.new('there is already one or more instance(s) of the program running') unless @applications.empty?
126
119
  end
127
-
120
+
128
121
  app = Application.new(self, add_options)
129
-
122
+
130
123
  setup_app(app)
131
-
124
+
132
125
  @applications << app
133
-
134
- return app
126
+
127
+ app
135
128
  end
136
-
129
+
137
130
  def setup_app(app)
138
131
  app.controller_argv = @controller_argv
139
132
  app.app_argv = @app_argv
133
+ if @options[:show_status_callback]
134
+ app.show_status_callback = @options[:show_status_callback]
135
+ end
140
136
  end
141
137
  private :setup_app
142
-
138
+
143
139
  def create_monitor(an_app)
144
- return if @monitor
145
-
140
+ if @monitor && options[:monitor]
141
+ @monitor.stop
142
+ @monitor = nil
143
+ end
144
+
146
145
  if options[:monitor]
147
146
  @monitor = Monitor.new(an_app)
148
-
149
- @monitor.start(@applications)
147
+ @monitor.start(self)
150
148
  end
151
149
  end
152
-
150
+
153
151
  def start_all
154
152
  @monitor.stop if @monitor
155
153
  @monitor = nil
156
-
157
- @applications.each {|a|
158
- fork {
159
- a.start
160
- }
161
- }
154
+
155
+ @applications.each do |a|
156
+ fork do
157
+ a.start
158
+ end
159
+ end
162
160
  end
163
-
161
+
164
162
  def stop_all(no_wait = false)
165
- @monitor.stop if @monitor
166
-
163
+ if @monitor
164
+ @monitor.stop
165
+ @monitor = nil
166
+ setup
167
+ end
168
+
167
169
  threads = []
168
-
169
- @applications.each {|a|
170
+
171
+ @applications.each do |a|
170
172
  threads << Thread.new do
171
173
  a.stop(no_wait)
172
174
  end
173
- }
174
-
175
- threads.each {|t| t.join}
175
+ end
176
+
177
+ threads.each { |t| t.join }
176
178
  end
177
-
179
+
178
180
  def reload_all
179
- @applications.each {|a| a.reload}
181
+ @applications.each { |a| a.reload }
180
182
  end
181
183
 
182
184
  def zap_all
183
185
  @monitor.stop if @monitor
184
-
185
- @applications.each {|a| a.zap}
186
+
187
+ @applications.each { |a| a.zap }
186
188
  end
187
-
189
+
188
190
  def show_status
189
- @applications.each {|a| a.show_status}
191
+ @applications.each { |a| a.show_status }
192
+ end
193
+
194
+ # Check whether at least one of the applications in the group is running. If yes, return true.
195
+ def running?
196
+ @applications.each { |a| return true if a.running? }
197
+ return false
190
198
  end
191
199
 
192
200
  end
193
-
194
201
  end
@@ -1,9 +1,9 @@
1
1
  require 'daemons/etc_extension'
2
2
 
3
3
  class CurrentProcess
4
- def self.change_privilege(user, group=user)
4
+ def self.change_privilege(user, group = user)
5
5
  puts "Changing process privilege to #{user}:#{group}"
6
-
6
+
7
7
  uid, gid = Process.euid, Process.egid
8
8
  target_uid = Etc.getpwnam(user).uid
9
9
  target_gid = Etc.getgrnam(group).gid
@@ -16,4 +16,4 @@ class CurrentProcess
16
16
  rescue Errno::EPERM => e
17
17
  raise "Couldn't change user and group to #{user}:#{group}: #{e}"
18
18
  end
19
- end
19
+ end
@@ -1,56 +1,52 @@
1
-
2
1
  module Daemons
3
-
4
2
  class Optparse
5
-
6
3
  attr_reader :usage
7
4
 
8
5
  def initialize(controller)
9
6
  @controller = controller
10
7
  @options = {}
11
-
8
+
12
9
  @opts = OptionParser.new do |opts|
13
- opts.banner = ""
14
-
10
+ opts.banner = ''
11
+
15
12
  # opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
16
13
  # @options[:verbose] = v
17
14
  # end
18
-
19
- opts.on("-t", "--ontop", "Stay on top (does not daemonize)") do |t|
15
+
16
+ opts.on('-t', '--ontop', 'Stay on top (does not daemonize)') do |t|
20
17
  @options[:ontop] = t
21
18
  end
22
-
23
- opts.on("-f", "--force", "Force operation") do |t|
19
+
20
+ opts.on('-f', '--force', 'Force operation') do |t|
24
21
  @options[:force] = t
25
22
  end
26
-
27
- opts.on("-n", "--no_wait", "Do not wait for processes to stop") do |t|
23
+
24
+ opts.on('-n', '--no_wait', 'Do not wait for processes to stop') do |t|
28
25
  @options[:no_wait] = t
29
26
  end
30
-
31
- #opts.separator ""
32
- #opts.separator "Specific options:"
33
27
 
34
-
35
- opts.separator ""
36
- opts.separator "Common options:"
28
+ # opts.separator ""
29
+ # opts.separator "Specific options:"
30
+
31
+ opts.separator ''
32
+ opts.separator 'Common options:'
37
33
 
38
34
  # No argument, shows at tail. This will print an options summary
39
- opts.on_tail("-h", "--help", "Show this message") do
40
- #puts opts
41
- #@usage =
42
- controller.print_usage()
43
-
35
+ opts.on_tail('-h', '--help', 'Show this message') do
36
+ # puts opts
37
+ # @usage =
38
+ controller.print_usage
39
+
44
40
  exit
45
41
  end
46
42
 
47
43
  # Switch to print the version.
48
- opts.on_tail("--version", "Show version") do
44
+ opts.on_tail('--version', 'Show version') do
49
45
  puts "daemons version #{Daemons::VERSION}"
50
46
  exit
51
47
  end
52
- end
53
-
48
+ end
49
+
54
50
  begin
55
51
  @usage = @opts.to_s
56
52
  rescue ::Exception # work around a bug in ruby 1.9
@@ -65,57 +61,50 @@ module Daemons
65
61
  END
66
62
  end
67
63
  end
68
-
69
-
64
+
70
65
  #
71
66
  # Return a hash describing the options.
72
67
  #
73
68
  def parse(args)
74
69
  # The options specified on the command line will be collected in *options*.
75
70
  # We set default values here.
76
- #options = {}
77
-
78
-
79
- ##pp args
71
+ # options = {}
72
+
73
+ # #pp args
80
74
  @opts.parse(args)
81
-
82
- return @options
83
- end
84
75
 
76
+ @options
77
+ end
85
78
  end
86
-
87
-
79
+
88
80
  class Controller
89
-
90
81
  def print_usage
91
82
  puts "Usage: #{@app_name} <command> <options> -- <application options>"
92
83
  puts
93
- puts "* where <command> is one of:"
94
- puts " start start an instance of the application"
95
- puts " stop stop all instances of the application"
96
- puts " restart stop all instances and restart them afterwards"
97
- puts " reload send a SIGHUP to all instances of the application"
98
- puts " run start the application and stay on top"
99
- puts " zap set the application to a stopped state"
100
- puts " status show status (PID) of application instances"
84
+ puts '* where <command> is one of:'
85
+ puts ' start start an instance of the application'
86
+ puts ' stop stop all instances of the application'
87
+ puts ' restart stop all instances and restart them afterwards'
88
+ puts ' reload send a SIGHUP to all instances of the application'
89
+ puts ' run start the application and stay on top'
90
+ puts ' zap set the application to a stopped state'
91
+ puts ' status show status (PID) of application instances'
101
92
  puts
102
- puts "* and where <options> may contain several of the following:"
103
-
93
+ puts '* and where <options> may contain several of the following:'
94
+
104
95
  puts @optparse.usage
105
96
  end
106
-
97
+
107
98
  def catch_exceptions(&block)
108
99
  begin
109
100
  block.call
110
101
  rescue CmdException, OptionParser::ParseError => e
111
- puts "ERROR: #{e.to_s}"
102
+ puts "ERROR: #{e}"
112
103
  puts
113
- print_usage()
104
+ print_usage
114
105
  rescue RuntimeException => e
115
- puts "ERROR: #{e.to_s}"
106
+ puts "ERROR: #{e}"
116
107
  end
117
108
  end
118
-
119
109
  end
120
-
121
110
  end