daemons 1.1.9 → 1.2.1

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