run_in_background 0.0.11 → 1.0.0

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.
@@ -22,17 +22,17 @@ rescue LoadError
22
22
  require 'log'
23
23
  end
24
24
 
25
- BBFS::Params['log_write_to_console'] = false
25
+ Params['log_write_to_console'] = false
26
26
  # On WindowsXP log can be found under:
27
27
  # C:/Documents and Settings/NetworkService/.bbfs/daemon_wrapper_<pid>.log
28
- BBFS::Params['log_file_name'] = File.join(Dir.home, '.bbfs', "#{File.basename(__FILE__)}_#{Process.pid}.log")
29
- BBFS::Log.init
28
+ Params['log_file_name'] = File.join(Dir.home, '.bbfs', "#{File.basename(__FILE__)}_#{Process.pid}.log")
29
+ Log.init
30
30
 
31
31
  class WrapperDaemon < Daemon
32
32
  def service_main
33
- BBFS::Log.info "Wrapper starts: #{ARGV.join(' ')}"
33
+ Log.info "Wrapper starts: #{ARGV.join(' ')}"
34
34
  @pid = Process.spawn ARGV.join(' ')
35
- BBFS::Log.debug1 "Wrapper inner app pid: #{@pid}"
35
+ Log.debug1 "Wrapper inner app pid: #{@pid}"
36
36
 
37
37
  while running?
38
38
  begin
@@ -40,7 +40,7 @@ class WrapperDaemon < Daemon
40
40
  Process.kill 0, @pid
41
41
  rescue Errno::ESRCH
42
42
  # if inner application exited then stop the service
43
- BBFS::Log.debug1 'Inner app no more running.'
43
+ Log.debug1 'Inner app no more running.'
44
44
  service_stop
45
45
  end
46
46
  sleep 0.5
@@ -64,49 +64,49 @@ class WrapperDaemon < Daemon
64
64
  begin
65
65
  Process.kill sig, @pid # kill the inner application
66
66
  rescue Exception => e
67
- BBFS::Log.debug1 "kill inner app with #{sig} signal failed: #{e.message}"
67
+ Log.debug1 "kill inner app with #{sig} signal failed: #{e.message}"
68
68
  sleep 1
69
69
  Process.kill sig, @pid # second try to kill the inner application
70
70
  end
71
71
  if alive? @pid
72
- BBFS::Log.debug1 'inner app still alive after kill. wait till exit...'
72
+ Log.debug1 'inner app still alive after kill. wait till exit...'
73
73
  # may be redundant. children processes on Windows look be detached.
74
74
  # also can be rather dangerous to use here.
75
75
  pid_exit_stat = Process.waitpid2 @pid
76
- BBFS::Log.debug1 "inner application exit status: #{pid_exit_stat}"
76
+ Log.debug1 "inner application exit status: #{pid_exit_stat}"
77
77
  if alive? @pid
78
- BBFS::Log.debug1 'inner app still alive after wait'
78
+ Log.debug1 'inner app still alive after wait'
79
79
  # this exception can be raised when using win32/process
80
80
  raise 'inner app still alive after wait'
81
81
  else
82
- BBFS::Log.debug1 'inner app deleted after wait'
82
+ Log.debug1 'inner app deleted after wait'
83
83
  end
84
84
  else
85
- BBFS::Log.debug1 'inner app was killed'
85
+ Log.debug1 'inner app was killed'
86
86
  end
87
87
  else
88
88
  # if got here then inner application is already exit. do nothing.
89
- BBFS::Log.debug1 'inner app already deleted'
89
+ Log.debug1 'inner app already deleted'
90
90
  end
91
91
  end
92
92
 
93
93
  def service_stop
94
- BBFS::Log.debug1 'service should be stopped'
94
+ Log.debug1 'service should be stopped'
95
95
  [1, 2, 6, 15, 22, 9].each do |sig|
96
96
  begin
97
- BBFS::Log.debug1 "signal #{sig} sent to kill inner app"
97
+ Log.debug1 "signal #{sig} sent to kill inner app"
98
98
  kill_inner_app sig
99
99
  rescue Exception => e
100
- BBFS::Log.debug1 "#{e.message}"
100
+ Log.debug1 "#{e.message}"
101
101
  next
102
102
  end
103
- BBFS::Log.debug1 'Wrapper was stopped'
103
+ Log.debug1 'Wrapper was stopped'
104
104
  # let log be written
105
- sleep BBFS::Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5
105
+ sleep Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5
106
106
  exit!
107
107
  end
108
- BBFS::Log.error 'Failed to stop service'
109
- sleep BBFS::Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5
108
+ Log.error 'Failed to stop service'
109
+ sleep Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5
110
110
  #exit!
111
111
  raise 'Failed to stop service'
112
112
  end
@@ -1,5 +1,3 @@
1
- module BBFS
2
- module RunInBackground
3
- VERSION = "0.0.11"
4
- end
1
+ module RunInBackground
2
+ VERSION = "1.0.0"
5
3
  end
@@ -4,430 +4,428 @@
4
4
  require 'params'
5
5
  require 'log'
6
6
 
7
- module BBFS
8
- # This library provides a basic cross-platform functionality to run arbitrary ruby scripts
9
- # in background and control them. <br>Supported platforms: Windows, Linux, Mac
10
- # NOTE UAC (User Account Control) should be disabled to use library on Windows 7:
11
- # * Click on the Windows Icon
12
- # * Click on the Control Panel
13
- # * Type in UAC in the search box (up-right corner of your window)
14
- # * Click on "Change User Account Control settings"
15
- # * Drag the slider down to either "Notify me when programs try to make changes to my computer"
16
- # or to disable it completely
17
- # * Reboot your computer when you're ready
18
- # == General Limitations:
19
- # * Only ruby scripts can be run in background.
20
- # * No multiple instances with the same name.
21
- # == Notes:
22
- # * Linux/Mac specific methods have _linux suffix
23
- # * Windows specific methods have _windows suffix
24
- # * While enhancing windows code, take care that paths are in windows format,
25
- # <br>e.i. with "\\" file separator while ruby by default uses a "/"
26
- # * Additional functionality such as restart, reload, etc. will be added on demand
27
- # * Remains support to provide platform specific options for start.
28
- # <br>For more information regarding such options
29
- # see documentation for win32-sevice (Windows), daemons (Linux/Mac)
30
- # == Linux Notes:
31
- # * <tt>pid_dir</tt> parameter contains absolute path to directory where pid files will be stored.
32
- # <br>If directory doesn't exists then it will be created.
33
- # <br>User should have a read/write permissions to this location.
34
- # <br>Default location: <tt>$HOME/.bbfs/pids</tt>
35
- # * User should check that default pid directory is free from pid files of "killed" daemons.
36
- # <br>It may happen, for example, when system finished in abnormal way then pid files were
37
- # not deleted by daemons library.
38
- # <br>In such case incorrect results can be received, for example for <tt>exists?</tt> method
39
- # <br>One of the suggested methods can be before starting a daemon to check with <tt>exists?</tt>
40
- # method whether daemon already exists and with <tt>running?</tt> method does it running.
41
- module RunInBackground
42
- Params.string('bg_command', nil, 'Server\'s command. Commands are: start, delete and nil for' \
7
+ # This library provides a basic cross-platform functionality to run arbitrary ruby scripts
8
+ # in background and control them. <br>Supported platforms: Windows, Linux, Mac
9
+ # NOTE UAC (User Account Control) should be disabled to use library on Windows 7:
10
+ # * Click on the Windows Icon
11
+ # * Click on the Control Panel
12
+ # * Type in UAC in the search box (up-right corner of your window)
13
+ # * Click on "Change User Account Control settings"
14
+ # * Drag the slider down to either "Notify me when programs try to make changes to my computer"
15
+ # or to disable it completely
16
+ # * Reboot your computer when you're ready
17
+ # == General Limitations:
18
+ # * Only ruby scripts can be run in background.
19
+ # * No multiple instances with the same name.
20
+ # == Notes:
21
+ # * Linux/Mac specific methods have _linux suffix
22
+ # * Windows specific methods have _windows suffix
23
+ # * While enhancing windows code, take care that paths are in windows format,
24
+ # <br>e.i. with "\\" file separator while ruby by default uses a "/"
25
+ # * Additional functionality such as restart, reload, etc. will be added on demand
26
+ # * Remains support to provide platform specific options for start.
27
+ # <br>For more information regarding such options
28
+ # see documentation for win32-sevice (Windows), daemons (Linux/Mac)
29
+ # == Linux Notes:
30
+ # * <tt>pid_dir</tt> parameter contains absolute path to directory where pid files will be stored.
31
+ # <br>If directory doesn't exists then it will be created.
32
+ # <br>User should have a read/write permissions to this location.
33
+ # <br>Default location: <tt>$HOME/.bbfs/pids</tt>
34
+ # * User should check that default pid directory is free from pid files of "killed" daemons.
35
+ # <br>It may happen, for example, when system finished in abnormal way then pid files were
36
+ # not deleted by daemons library.
37
+ # <br>In such case incorrect results can be received, for example for <tt>exists?</tt> method
38
+ # <br>One of the suggested methods can be before starting a daemon to check with <tt>exists?</tt>
39
+ # method whether daemon already exists and with <tt>running?</tt> method does it running.
40
+ module RunInBackground
41
+ Params.string('bg_command', nil, 'Server\'s command. Commands are: start, delete and nil for' \
43
42
  ' not running in background.')
44
- Params.string('service_name', File.basename($0), 'Background service name.')
45
-
46
- # Maximal time in seconds to wait until OS will finish a requested operation,
47
- # e.g. daemon start/delete.
48
- TIMEOUT = 20
49
-
50
- if RUBY_PLATFORM =~ /linux/ or RUBY_PLATFORM =~ /darwin/
51
- begin
52
- require 'daemons'
53
- require 'fileutils'
54
- rescue LoadError
55
- require 'rubygems'
56
- require 'daemons'
57
- require 'fileutils'
58
- end
43
+ Params.string('service_name', File.basename($0), 'Background service name.')
44
+
45
+ # Maximal time in seconds to wait until OS will finish a requested operation,
46
+ # e.g. daemon start/delete.
47
+ TIMEOUT = 20
48
+
49
+ if RUBY_PLATFORM =~ /linux/ or RUBY_PLATFORM =~ /darwin/
50
+ begin
51
+ require 'daemons'
52
+ require 'fileutils'
53
+ rescue LoadError
54
+ require 'rubygems'
55
+ require 'daemons'
56
+ require 'fileutils'
57
+ end
59
58
 
60
- OS = :LINUX
61
- Params.string('pid_dir', File.expand_path(File.join(Dir.home, '.bbfs', 'pids')),
62
- 'Absolute path to directory, where pid files will be stored. ' + \
59
+ OS = :LINUX
60
+ Params.string('pid_dir', File.expand_path(File.join(Dir.home, '.bbfs', 'pids')),
61
+ 'Absolute path to directory, where pid files will be stored. ' + \
63
62
  'User should have a read/write permissions to this location. ' + \
64
63
  'If absent then it will be created. ' + \
65
64
  'It\'s actual only for Linux/Mac. ' + \
66
65
  'For more information see documentation on daemons module. ' +\
67
66
  'Default location is: $HOME/.bbfs/pids')
68
67
 
69
- if Dir.exists? Params['pid_dir']
70
- unless File.directory? Params['pid_dir']
71
- raise IOError.new("pid directory #{Params['pid_dir']} should be a directory")
72
- end
73
- unless File.readable?(Params['pid_dir']) && File.writable?(Params['pid_dir'])
74
- raise IOError.new("you should have read/write permissions to pid dir: #{Params['pid_dir']}")
75
- end
76
- else
77
- ::FileUtils.mkdir_p Params['pid_dir']
68
+ if Dir.exists? Params['pid_dir']
69
+ unless File.directory? Params['pid_dir']
70
+ raise IOError.new("pid directory #{Params['pid_dir']} should be a directory")
78
71
  end
79
- elsif RUBY_PLATFORM =~ /mingw/ or RUBY_PLATFORM =~ /ms/ or RUBY_PLATFORM =~ /win/
80
- require 'rbconfig'
81
- begin
82
- require 'win32/service'
83
- require 'win32/daemon'
84
- rescue LoadError
85
- require 'rubygems'
86
- require 'win32/service'
87
- require 'win32/daemon'
72
+ unless File.readable?(Params['pid_dir']) && File.writable?(Params['pid_dir'])
73
+ raise IOError.new("you should have read/write permissions to pid dir: #{Params['pid_dir']}")
88
74
  end
89
- include Win32
90
-
91
- OS = :WINDOWS
92
- # Get ruby interpreter path. Need it to run ruby binary.
93
- # <br>TODO check whether this code works with Windows Ruby Version Management (e.g. Pik)
94
- RUBY_INTERPRETER_PATH = File.join(Config::CONFIG["bindir"],
95
- Config::CONFIG["RUBY_INSTALL_NAME"] +
96
- Config::CONFIG["EXEEXT"]).tr!('/','\\')
97
-
98
- # Path has to be absolute cause Win32-Service demands it.
99
- wrapper = File.join(File.dirname(__FILE__), "..", "bin", File.basename(__FILE__, ".rb"), "daemon_wrapper")
100
- # Wrapper script, that can receive commands from Windows Service Control and run user script,
101
- # <br> provided as it's argument
102
- WRAPPER_SCRIPT = File.expand_path(wrapper).tr!('/','\\')
103
75
  else
104
- raise "Unsupported platform #{RUBY_PLATFORM}"
76
+ ::FileUtils.mkdir_p Params['pid_dir']
77
+ end
78
+ elsif RUBY_PLATFORM =~ /mingw/ or RUBY_PLATFORM =~ /ms/ or RUBY_PLATFORM =~ /win/
79
+ require 'rbconfig'
80
+ begin
81
+ require 'win32/service'
82
+ require 'win32/daemon'
83
+ rescue LoadError
84
+ require 'rubygems'
85
+ require 'win32/service'
86
+ require 'win32/daemon'
105
87
  end
88
+ include Win32
89
+
90
+ OS = :WINDOWS
91
+ # Get ruby interpreter path. Need it to run ruby binary.
92
+ # <br>TODO check whether this code works with Windows Ruby Version Management (e.g. Pik)
93
+ RUBY_INTERPRETER_PATH = File.join(Config::CONFIG["bindir"],
94
+ Config::CONFIG["RUBY_INSTALL_NAME"] +
95
+ Config::CONFIG["EXEEXT"]).tr!('/','\\')
96
+
97
+ # Path has to be absolute cause Win32-Service demands it.
98
+ wrapper = File.join(File.dirname(__FILE__), "..", "bin", File.basename(__FILE__, ".rb"), "daemon_wrapper")
99
+ # Wrapper script, that can receive commands from Windows Service Control and run user script,
100
+ # <br> provided as it's argument
101
+ WRAPPER_SCRIPT = File.expand_path(wrapper).tr!('/','\\')
102
+ else
103
+ raise "Unsupported platform #{RUBY_PLATFORM}"
104
+ end
106
105
 
107
- # Start a service/daemon.
108
- # <br>It important to delete it after usage.
109
- # ==== Arguments
110
- # * <tt>binary_path</tt> - absolute path to the script that should be run in background
111
- # NOTE for Linux script should be executable and with UNIX end-of-lines (LF).
112
- # * <tt>binary_args</tt> - Array (not nil) of script's command line arguments
113
- # * <tt>name</tt> - service/daemon name.
114
- # NOTE should be unique
115
- # * <tt>opts_specific</tt> - Hash of platform specific options (only for more specific usage)
116
- # For more information regarding such options see documentation for
117
- # win32-sevice (Windows), daemons (Linux/Mac)
118
- # ==== Example (LINUX)
119
- # <tt> RunInBackground.start "/home/user/test_app", [], "daemon_test", {:monitor => true}</tt>
120
- def RunInBackground.start binary_path, binary_args, name, opts_specific = {}
121
- Log.debug1("executable that should be run as daemon/service: #{binary_path}")
122
- Log.debug1("arguments: #{binary_args}")
123
- Log.debug1("specific options: #{opts_specific}")
124
-
125
- if binary_path == nil or binary_args == nil or name == nil
126
- Log.error("binary path, binary args, name arguments must be defined")
127
- raise ArgumentError.new("binary path, binary args, name arguments must be defined")
128
- end
106
+ # Start a service/daemon.
107
+ # <br>It important to delete it after usage.
108
+ # ==== Arguments
109
+ # * <tt>binary_path</tt> - absolute path to the script that should be run in background
110
+ # NOTE for Linux script should be executable and with UNIX end-of-lines (LF).
111
+ # * <tt>binary_args</tt> - Array (not nil) of script's command line arguments
112
+ # * <tt>name</tt> - service/daemon name.
113
+ # NOTE should be unique
114
+ # * <tt>opts_specific</tt> - Hash of platform specific options (only for more specific usage)
115
+ # For more information regarding such options see documentation for
116
+ # win32-sevice (Windows), daemons (Linux/Mac)
117
+ # ==== Example (LINUX)
118
+ # <tt> RunInBackground.start "/home/user/test_app", [], "daemon_test", {:monitor => true}</tt>
119
+ def RunInBackground.start binary_path, binary_args, name, opts_specific = {}
120
+ Log.debug1("executable that should be run as daemon/service: #{binary_path}")
121
+ Log.debug1("arguments: #{binary_args}")
122
+ Log.debug1("specific options: #{opts_specific}")
123
+
124
+ if binary_path == nil or binary_args == nil or name == nil
125
+ Log.error("binary path, binary args, name arguments must be defined")
126
+ raise ArgumentError.new("binary path, binary args, name arguments must be defined")
127
+ end
129
128
 
130
- if OS == :WINDOWS
131
- new_binary_path = String.new(binary_path)
132
- new_binary_args = Array.new(binary_args)
133
- wrap_windows new_binary_path, new_binary_args
134
- start_windows new_binary_path, new_binary_args, name, opts_specific
135
- else # OS == LINUX
136
- start_linux binary_path, binary_args, name, opts_specific
137
- end
129
+ if OS == :WINDOWS
130
+ new_binary_path = String.new(binary_path)
131
+ new_binary_args = Array.new(binary_args)
132
+ wrap_windows new_binary_path, new_binary_args
133
+ start_windows new_binary_path, new_binary_args, name, opts_specific
134
+ else # OS == LINUX
135
+ start_linux binary_path, binary_args, name, opts_specific
136
+ end
138
137
 
139
- 0.upto(TIMEOUT) do
140
- if exists?(name) && running?(name)
141
- puts "daemon/service #{name} started\n"
142
- Log.info("daemon/service #{name} started")
143
- return
144
- end
145
- sleep 1
138
+ 0.upto(TIMEOUT) do
139
+ if exists?(name) && running?(name)
140
+ puts "daemon/service #{name} started\n"
141
+ Log.info("daemon/service #{name} started")
142
+ return
146
143
  end
147
- # if got here then something gone wrong and daemon/service wasn't started in timely manner
148
- delete name if exists? name
149
- Log.error("daemon/service #{name} wasn't started in timely manner")
150
- sleep(Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5)
151
- raise "daemon/service #{name} wasn't started in timely manner"
144
+ sleep 1
152
145
  end
146
+ # if got here then something gone wrong and daemon/service wasn't started in timely manner
147
+ delete name if exists? name
148
+ Log.error("daemon/service #{name} wasn't started in timely manner")
149
+ sleep(Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5)
150
+ raise "daemon/service #{name} wasn't started in timely manner"
151
+ end
153
152
 
154
- def RunInBackground.start_linux binary_path, binary_args, name, opts = {}
155
- unless File.executable? binary_path
156
- raise ArgumentError.new("#{binary_path} is not executable.")
157
- end
153
+ def RunInBackground.start_linux binary_path, binary_args, name, opts = {}
154
+ unless File.executable? binary_path
155
+ raise ArgumentError.new("#{binary_path} is not executable.")
156
+ end
158
157
 
159
- if opts.has_key? :dir
160
- raise ArgumentError.new("No support for user-defined pid directories. See help")
161
- end
158
+ if opts.has_key? :dir
159
+ raise ArgumentError.new("No support for user-defined pid directories. See help")
160
+ end
162
161
 
163
- opts[:app_name] = name
164
- opts[:ARGV] = ['start']
165
- (opts[:ARGV] << '--').concat(binary_args) if !binary_args.nil? && binary_args.size > 0
166
- opts[:dir] = Params['pid_dir']
167
- opts[:dir_mode] = :normal
162
+ opts[:app_name] = name
163
+ opts[:ARGV] = ['start']
164
+ (opts[:ARGV] << '--').concat(binary_args) if !binary_args.nil? && binary_args.size > 0
165
+ opts[:dir] = Params['pid_dir']
166
+ opts[:dir_mode] = :normal
168
167
 
169
- Log.debug1("binary path: #{binary_path}")
170
- Log.debug1("opts: #{opts}")
168
+ Log.debug1("binary path: #{binary_path}")
169
+ Log.debug1("opts: #{opts}")
171
170
 
172
- # Current process, that creates daemon, will transfer control to the Daemons library.
173
- # So to continue working with current process, daemon creation initiated from separate process.
174
- pid = fork do
175
- Daemons.run binary_path, opts
176
- end
177
- Process.waitpid pid
171
+ # Current process, that creates daemon, will transfer control to the Daemons library.
172
+ # So to continue working with current process, daemon creation initiated from separate process.
173
+ pid = fork do
174
+ Daemons.run binary_path, opts
178
175
  end
176
+ Process.waitpid pid
177
+ end
179
178
 
180
- def RunInBackground.start_windows binary_path, binary_args, name, opts = {}
181
- raise ArgumentError.new("#{binary_path} doesn't exist'") unless File.exists? binary_path
179
+ def RunInBackground.start_windows binary_path, binary_args, name, opts = {}
180
+ raise ArgumentError.new("#{binary_path} doesn't exist'") unless File.exists? binary_path
182
181
 
183
- # path that contains spaces must be escaped to be interpreted correctly
184
- binary_path = %Q{"#{binary_path}"} if binary_path =~ / /
185
- binary_path.tr!('/','\\')
186
- # service should be run with the same load path as a current application
187
- load_path = get_load_path
188
- binary_args_str = binary_args.join ' '
182
+ # path that contains spaces must be escaped to be interpreted correctly
183
+ binary_path = %Q{"#{binary_path}"} if binary_path =~ / /
184
+ binary_path.tr!('/','\\')
185
+ # service should be run with the same load path as a current application
186
+ load_path = get_load_path
187
+ binary_args_str = binary_args.join ' '
189
188
 
190
- opts[:binary_path_name] = \
189
+ opts[:binary_path_name] = \
191
190
  "#{RUBY_INTERPRETER_PATH} #{load_path} #{binary_path} #{binary_args_str}"
192
- # quotation marks must be escaped cause of ARGV parsing
193
- opts[:binary_path_name] = opts[:binary_path_name].gsub '"', '"\\"'
194
- opts[:service_name] = name
195
- opts[:description] = name unless opts.has_key? :description
196
- opts[:display_name] = name unless opts.has_key? :display_name
197
- opts[:service_type] = Service::WIN32_OWN_PROCESS unless opts.has_key? :service_type
198
- opts[:start_type] = Service::DEMAND_START unless opts.has_key? :start_type
199
-
200
- # NOTE most of examples uses these dependencies. Meanwhile no explanations were found
201
- opts[:dependencies] = ['W32Time','Schedule'] unless opts.has_key? :dependencies
202
- # NOTE most of examples uses this option as defined beneath. The default is nil.
203
- #opts[:load_order_group] = 'Network' unless opts.has_key? :load_order_group
204
-
205
- Log.debug1("create service options: #{opts}")
206
- Service.create(opts)
207
- begin
208
- Service.start(opts[:service_name])
209
- rescue
210
- Service.delete(opts[:service_name]) if Service.exists?(opts[:service_name])
211
- raise
212
- end
191
+ # quotation marks must be escaped cause of ARGV parsing
192
+ opts[:binary_path_name] = opts[:binary_path_name].gsub '"', '"\\"'
193
+ opts[:service_name] = name
194
+ opts[:description] = name unless opts.has_key? :description
195
+ opts[:display_name] = name unless opts.has_key? :display_name
196
+ opts[:service_type] = Service::WIN32_OWN_PROCESS unless opts.has_key? :service_type
197
+ opts[:start_type] = Service::DEMAND_START unless opts.has_key? :start_type
198
+
199
+ # NOTE most of examples uses these dependencies. Meanwhile no explanations were found
200
+ opts[:dependencies] = ['W32Time','Schedule'] unless opts.has_key? :dependencies
201
+ # NOTE most of examples uses this option as defined beneath. The default is nil.
202
+ #opts[:load_order_group] = 'Network' unless opts.has_key? :load_order_group
203
+
204
+ Log.debug1("create service options: #{opts}")
205
+ Service.create(opts)
206
+ begin
207
+ Service.start(opts[:service_name])
208
+ rescue
209
+ Service.delete(opts[:service_name]) if Service.exists?(opts[:service_name])
210
+ raise
213
211
  end
212
+ end
214
213
 
215
- # Rerun current script in background.
216
- # <br>Current process will be closed.
217
- # <br>It suggested to remove from ARGV any command line arguments that point
218
- # to run script in background, <br>otherwise an unexpexted result can be received
219
- def RunInBackground.start! name, opts = {}
220
- # $0 is the executable name.
221
- start(File.expand_path($0), ARGV, name, opts)
222
- sleep Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5
223
- exit!
224
- end
214
+ # Rerun current script in background.
215
+ # <br>Current process will be closed.
216
+ # <br>It suggested to remove from ARGV any command line arguments that point
217
+ # to run script in background, <br>otherwise an unexpexted result can be received
218
+ def RunInBackground.start! name, opts = {}
219
+ # $0 is the executable name.
220
+ start(File.expand_path($0), ARGV, name, opts)
221
+ sleep Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5
222
+ exit!
223
+ end
225
224
 
226
- # Run in background script that was written as Windows Service, i.e. can receive signals
227
- # from Service Control.
228
- # <br>The code that is run in this script should be an extension of Win32::Daemon class.
229
- # <br>For more information see Win32::Daemon help and examples.
230
- # <br>No need to wrap such a script.
231
- def RunInBackground.start_win32service binary_path, binary_args, name, opts_specific = {}
232
- Log.debug1("executable that should be run as service: #{binary_path}")
233
- Log.debug1("arguments: #{binary_args}")
234
- Log.debug1("specific options: #{opts_specific}")
235
-
236
- if OS == :WINDOWS
237
- start_windows binary_path, binary_args, name, opts_specific
238
- else # OS == :LINUX
239
- raise NotImplementedError.new("Unsupported method on #{OS}")
240
- end
241
- 0.upto(TIMEOUT) do
242
- if exists?(name) && running?(name)
243
- puts "windows service #{name} started\n"
244
- Log.info("windows service #{name} started")
245
- return
246
- end
247
- sleep 1
225
+ # Run in background script that was written as Windows Service, i.e. can receive signals
226
+ # from Service Control.
227
+ # <br>The code that is run in this script should be an extension of Win32::Daemon class.
228
+ # <br>For more information see Win32::Daemon help and examples.
229
+ # <br>No need to wrap such a script.
230
+ def RunInBackground.start_win32service binary_path, binary_args, name, opts_specific = {}
231
+ Log.debug1("executable that should be run as service: #{binary_path}")
232
+ Log.debug1("arguments: #{binary_args}")
233
+ Log.debug1("specific options: #{opts_specific}")
234
+
235
+ if OS == :WINDOWS
236
+ start_windows binary_path, binary_args, name, opts_specific
237
+ else # OS == :LINUX
238
+ raise NotImplementedError.new("Unsupported method on #{OS}")
239
+ end
240
+ 0.upto(TIMEOUT) do
241
+ if exists?(name) && running?(name)
242
+ puts "windows service #{name} started\n"
243
+ Log.info("windows service #{name} started")
244
+ return
248
245
  end
249
- # if got here then something gone wrong and daemon/service wasn't started in timely manner
250
- delete name if exists? name
251
- Log.error("daemon/service #{name} wasn't started in timely manner")
252
- sleep(Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5)
253
- raise "daemon/service #{name} wasn't started in timely manner"
246
+ sleep 1
254
247
  end
248
+ # if got here then something gone wrong and daemon/service wasn't started in timely manner
249
+ delete name if exists? name
250
+ Log.error("daemon/service #{name} wasn't started in timely manner")
251
+ sleep(Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5)
252
+ raise "daemon/service #{name} wasn't started in timely manner"
253
+ end
255
254
 
256
- # Wrap an arbitrary ruby script withing script that can be run as Windows Service.
257
- # ==== Arguments
258
- # * <tt>binary_path</tt> - absolute path of the script that should be run in background
259
- # * <tt>binary_args</tt> - array (not nil) of scripts command line arguments
260
- #
261
- # NOTE binary_path and binary_args contents will be change
262
- def RunInBackground.wrap_windows binary_path, binary_args
263
- raise ArgumentError.new("#{binary_path} doesn't exists") unless File.exists? binary_path
264
-
265
- # service should be run with the same load path as a current application
266
- load_path = get_load_path
267
- # path that contains spaces must be escaped to be interpreted correctly
268
- binary_path = %Q{"#{binary_path}"} if binary_path =~ / /
269
- binary_args.insert(0, RUBY_INTERPRETER_PATH, load_path, binary_path.tr('/','\\'))
270
- binary_path.replace(WRAPPER_SCRIPT)
271
- end
255
+ # Wrap an arbitrary ruby script withing script that can be run as Windows Service.
256
+ # ==== Arguments
257
+ # * <tt>binary_path</tt> - absolute path of the script that should be run in background
258
+ # * <tt>binary_args</tt> - array (not nil) of scripts command line arguments
259
+ #
260
+ # NOTE binary_path and binary_args contents will be change
261
+ def RunInBackground.wrap_windows binary_path, binary_args
262
+ raise ArgumentError.new("#{binary_path} doesn't exists") unless File.exists? binary_path
263
+
264
+ # service should be run with the same load path as a current application
265
+ load_path = get_load_path
266
+ # path that contains spaces must be escaped to be interpreted correctly
267
+ binary_path = %Q{"#{binary_path}"} if binary_path =~ / /
268
+ binary_args.insert(0, RUBY_INTERPRETER_PATH, load_path, binary_path.tr('/','\\'))
269
+ binary_path.replace(WRAPPER_SCRIPT)
270
+ end
272
271
 
273
- # NOTE if this method will become public then may be needed to change appropriately wrapper script
274
- def RunInBackground.stop name
275
- if not exists? name
276
- raise ArgumentError.new("Daemon #{name} doesn't exists")
277
- elsif OS == :WINDOWS
278
- Service.stop(name)
279
- else # OS == :LINUX
280
- opts = {:app_name => name,
281
- :ARGV => ['stop'],
282
- :dir_mode => :normal,
283
- :dir => Params['pid_dir']
284
- }
285
- # Current process, that creates daemon, will transfer control to the Daemons library.
286
- # So to continue working with current process, daemon creation initiated from separate process.
287
- # It looks that it holds only for start command
288
- #pid = fork do
289
- Daemons.run "", opts
290
- #end
291
- #Process.waitpid pid
292
- end
272
+ # NOTE if this method will become public then may be needed to change appropriately wrapper script
273
+ def RunInBackground.stop name
274
+ if not exists? name
275
+ raise ArgumentError.new("Daemon #{name} doesn't exists")
276
+ elsif OS == :WINDOWS
277
+ Service.stop(name)
278
+ else # OS == :LINUX
279
+ opts = {:app_name => name,
280
+ :ARGV => ['stop'],
281
+ :dir_mode => :normal,
282
+ :dir => Params['pid_dir']
283
+ }
284
+ # Current process, that creates daemon, will transfer control to the Daemons library.
285
+ # So to continue working with current process, daemon creation initiated from separate process.
286
+ # It looks that it holds only for start command
287
+ #pid = fork do
288
+ Daemons.run "", opts
289
+ #end
290
+ #Process.waitpid pid
293
291
  end
292
+ end
294
293
 
295
- # Delete service/daemon.
296
- # <br>If running then stop and delete.
297
- def RunInBackground.delete name
298
- if not exists? name
299
- raise ArgumentError.new("Daemon #{name} doesn't exists")
300
- elsif running? name
301
- stop name
302
- end
303
- if OS == :WINDOWS
304
- Service.delete name
305
- else # OS == :LINUX
306
- opts = {:app_name => name,
307
- :ARGV => ['zap'],
308
- :dir_mode => :normal,
309
- :dir => Params['pid_dir']
310
- }
311
- # Current process, that creates daemon, will transfer control to the Daemons library.
312
- # So to continue working with current process, daemon creation initiated from separate process.
313
- # It looks that it holds only for start command
314
- #pid = fork do
315
- Daemons.run "", opts
316
- #end
317
- #Process.waitpid pid
318
- end
319
- 0.upto(TIMEOUT) do
320
- unless exists? name
321
- puts "daemon/service #{name} deleted\n"
322
- Log.info("daemon/service #{name} deleted")
323
- return
324
- end
325
- sleep 1
326
- end
327
- # if got here then something gone wrong and daemon/service wasn't deleted in timely manner
328
- Log.error("daemon/service #{name} wasn't deleted in timely manner")
329
- sleep(Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5)
330
- raise "daemon/service #{name} wasn't deleted in timely manner"
294
+ # Delete service/daemon.
295
+ # <br>If running then stop and delete.
296
+ def RunInBackground.delete name
297
+ if not exists? name
298
+ raise ArgumentError.new("Daemon #{name} doesn't exists")
299
+ elsif running? name
300
+ stop name
331
301
  end
332
-
333
- def RunInBackground.exists? name
334
- if name == nil
335
- raise ArgumentError.new("service/daemon name argument must be defined")
336
- elsif OS == :WINDOWS
337
- Service.exists? name
338
- else # OS == :LINUX
339
- pid_files = Daemons::PidFile.find_files(Params['pid_dir'], name)
340
- pid_files != nil && pid_files.size > 0
302
+ if OS == :WINDOWS
303
+ Service.delete name
304
+ else # OS == :LINUX
305
+ opts = {:app_name => name,
306
+ :ARGV => ['zap'],
307
+ :dir_mode => :normal,
308
+ :dir => Params['pid_dir']
309
+ }
310
+ # Current process, that creates daemon, will transfer control to the Daemons library.
311
+ # So to continue working with current process, daemon creation initiated from separate process.
312
+ # It looks that it holds only for start command
313
+ #pid = fork do
314
+ Daemons.run "", opts
315
+ #end
316
+ #Process.waitpid pid
317
+ end
318
+ 0.upto(TIMEOUT) do
319
+ unless exists? name
320
+ puts "daemon/service #{name} deleted\n"
321
+ Log.info("daemon/service #{name} deleted")
322
+ return
341
323
  end
324
+ sleep 1
342
325
  end
326
+ # if got here then something gone wrong and daemon/service wasn't deleted in timely manner
327
+ Log.error("daemon/service #{name} wasn't deleted in timely manner")
328
+ sleep(Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] + 0.5)
329
+ raise "daemon/service #{name} wasn't deleted in timely manner"
330
+ end
343
331
 
344
- def RunInBackground.running? name
345
- if not exists? name
346
- raise ArgumentError.new("Daemon #{name} doesn't exists")
347
- elsif OS == :WINDOWS
348
- Service.status(name).current_state == 'running'
349
- else # OS == :LINUX
350
- Daemons::Pid.running? name
351
- end
332
+ def RunInBackground.exists? name
333
+ if name == nil
334
+ raise ArgumentError.new("service/daemon name argument must be defined")
335
+ elsif OS == :WINDOWS
336
+ Service.exists? name
337
+ else # OS == :LINUX
338
+ pid_files = Daemons::PidFile.find_files(Params['pid_dir'], name)
339
+ pid_files != nil && pid_files.size > 0
352
340
  end
341
+ end
353
342
 
354
- # Returns absolute standard form of the path.
355
- # It includes path separators accepted on this OS
356
- def RunInBackground.get_abs_std_path path
357
- path = File.expand_path path
358
- path = path.tr('/','\\') if OS == :WINDOWS
359
- path
343
+ def RunInBackground.running? name
344
+ if not exists? name
345
+ raise ArgumentError.new("Daemon #{name} doesn't exists")
346
+ elsif OS == :WINDOWS
347
+ Service.status(name).current_state == 'running'
348
+ else # OS == :LINUX
349
+ Daemons::Pid.running? name
360
350
  end
351
+ end
361
352
 
362
- # Returns load path as it provided in command line.
363
- def RunInBackground.get_load_path
364
- load_path = Array.new
365
- $:.each do |location|
366
- load_path << %Q{-I"#{get_abs_std_path(location)}"}
367
- end
368
- load_path.join ' '
353
+ # Returns absolute standard form of the path.
354
+ # It includes path separators accepted on this OS
355
+ def RunInBackground.get_abs_std_path path
356
+ path = File.expand_path path
357
+ path = path.tr('/','\\') if OS == :WINDOWS
358
+ path
359
+ end
360
+
361
+ # Returns load path as it provided in command line.
362
+ def RunInBackground.get_load_path
363
+ load_path = Array.new
364
+ $:.each do |location|
365
+ load_path << %Q{-I"#{get_abs_std_path(location)}"}
369
366
  end
367
+ load_path.join ' '
368
+ end
370
369
 
371
- # Prepare ARGV so it can be provided as a command line arguments.
372
- # Remove bg_command from ARGV to prevent infinite recursion.
373
- def RunInBackground.prepare_argv
374
- new_argv = Array.new
375
- ARGV.each do |arg|
376
- # For each argument try splitting to 'name'='value'
377
- arg_arr = arg.split '='
378
- # If no '=' is argument, just copy paste.
379
- if arg_arr.size == 1
380
- arg = "\"#{arg}\"" if arg =~ / /
381
- new_argv << arg
370
+ # Prepare ARGV so it can be provided as a command line arguments.
371
+ # Remove bg_command from ARGV to prevent infinite recursion.
372
+ def RunInBackground.prepare_argv
373
+ new_argv = Array.new
374
+ ARGV.each do |arg|
375
+ # For each argument try splitting to 'name'='value'
376
+ arg_arr = arg.split '='
377
+ # If no '=' is argument, just copy paste.
378
+ if arg_arr.size == 1
379
+ arg = "\"#{arg}\"" if arg =~ / /
380
+ new_argv << arg
382
381
  # If it is a 'name'='value' argument add "" so the value can be passed as argument again.
383
- elsif arg_arr.size == 2
384
- # Skip bg_command flag (remove infinite recursion)!
385
- if arg_arr[0] !~ /bg_command/
386
- arg_arr[1] = "\"#{arg_arr[1]}\"" if arg_arr[1] =~ / /
387
- new_argv << arg_arr.join('=')
388
- end
389
- else
390
- Log.warning("ARGV argument #{arg} wasn't processed")
391
- new_argv << arg
382
+ elsif arg_arr.size == 2
383
+ # Skip bg_command flag (remove infinite recursion)!
384
+ if arg_arr[0] !~ /bg_command/
385
+ arg_arr[1] = "\"#{arg_arr[1]}\"" if arg_arr[1] =~ / /
386
+ new_argv << arg_arr.join('=')
392
387
  end
388
+ else
389
+ Log.warning("ARGV argument #{arg} wasn't processed")
390
+ new_argv << arg
393
391
  end
394
- ARGV.clear
395
- ARGV.concat new_argv
396
392
  end
393
+ ARGV.clear
394
+ ARGV.concat new_argv
395
+ end
397
396
 
398
- def RunInBackground.run &b
399
- case Params['bg_command']
400
- when nil
401
- yield b
402
- when 'start'
403
- # To prevent service enter loop cause of background parameter
404
- # all options that points to run in background must be disabled
405
- # (for more information see documentation for RunInBackground::start!)
406
- Params['bg_command'] = nil
407
- RunInBackground.prepare_argv
408
-
409
- begin
410
- RunInBackground.start! Params['service_name']
411
- rescue Exception => e
412
- Log.error("Start service command failed: #{e.message}")
413
- raise
414
- end
415
- when 'delete'
416
- if RunInBackground.exists? Params['service_name']
417
- RunInBackground.delete Params['service_name']
418
- else
419
- msg = "Can't delete. Service #{Params['service_name']} already deleted"
420
- puts msg
421
- Log.warning(msg)
422
- end
397
+ def RunInBackground.run &b
398
+ case Params['bg_command']
399
+ when nil
400
+ yield b
401
+ when 'start'
402
+ # To prevent service enter loop cause of background parameter
403
+ # all options that points to run in background must be disabled
404
+ # (for more information see documentation for RunInBackground::start!)
405
+ Params['bg_command'] = nil
406
+ RunInBackground.prepare_argv
407
+
408
+ begin
409
+ RunInBackground.start! Params['service_name']
410
+ rescue Exception => e
411
+ Log.error("Start service command failed: #{e.message}")
412
+ raise
413
+ end
414
+ when 'delete'
415
+ if RunInBackground.exists? Params['service_name']
416
+ RunInBackground.delete Params['service_name']
423
417
  else
424
- msg = "Unsupported command #{Params['bg_command']}. Supported commands are: start, delete"
418
+ msg = "Can't delete. Service #{Params['service_name']} already deleted"
425
419
  puts msg
426
- Log.error(msg)
427
- end
420
+ Log.warning(msg)
421
+ end
422
+ else
423
+ msg = "Unsupported command #{Params['bg_command']}. Supported commands are: start, delete"
424
+ puts msg
425
+ Log.error(msg)
428
426
  end
427
+ end
429
428
 
430
- private_class_method :start_linux, :start_windows, :wrap_windows, :stop, :get_abs_std_path,\
429
+ private_class_method :start_linux, :start_windows, :wrap_windows, :stop, :get_abs_std_path, \
431
430
  :get_load_path
432
- end
433
431
  end
@@ -1,124 +1,122 @@
1
1
  require 'test/unit'
2
2
  require 'run_in_background'
3
3
 
4
- module BBFS
5
- # TODO break to number of small tests according to functionality
6
- # TODO rewrite with Shoulda/RSpec
7
- class TestRunInBackground < Test::Unit::TestCase
8
- #include BBFS::RunInBackground
4
+ # TODO break to number of small tests according to functionality
5
+ # TODO rewrite with Shoulda/RSpec
6
+ class TestRunInBackground < Test::Unit::TestCase
7
+ #include RunInBackground
9
8
 
10
- if RUBY_PLATFORM =~ /linux/ or RUBY_PLATFORM =~ /darwin/
11
- OS = :LINUX
12
- elsif RUBY_PLATFORM =~ /mingw/ or RUBY_PLATFORM =~ /ms/ or RUBY_PLATFORM =~ /win/
13
- require 'sys/uname'
14
- OS = :WINDOWS
15
- else
16
- raise "Unsupported platform #{RUBY_PLATFORM}"
17
- end
9
+ if RUBY_PLATFORM =~ /linux/ or RUBY_PLATFORM =~ /darwin/
10
+ OS = :LINUX
11
+ elsif RUBY_PLATFORM =~ /mingw/ or RUBY_PLATFORM =~ /ms/ or RUBY_PLATFORM =~ /win/
12
+ require 'sys/uname'
13
+ OS = :WINDOWS
14
+ else
15
+ raise "Unsupported platform #{RUBY_PLATFORM}"
16
+ end
18
17
 
19
- def setup
20
- @good_daemon = "good_daemon_test"
21
- @good_daemonize = "good_daemonize_test"
22
- @good_win32daemon = "good_win32daemon_test"
23
- @bad_daemon = "bad_daemon_test"
24
- @binary = File.join(File.dirname(File.expand_path(__FILE__)), 'test_app')
25
- @binary.tr!('/','\\') if OS == :WINDOWS
26
- File.chmod(0755, @binary) if OS == :LINUX && !File.executable?(@binary)
27
- @absent_binary = File.join(File.dirname(File.expand_path(__FILE__)), "test_app_absent")
28
- end
18
+ def setup
19
+ @good_daemon = "good_daemon_test"
20
+ @good_daemonize = "good_daemonize_test"
21
+ @good_win32daemon = "good_win32daemon_test"
22
+ @bad_daemon = "bad_daemon_test"
23
+ @binary = File.join(File.dirname(File.expand_path(__FILE__)), 'test_app')
24
+ @binary.tr!('/','\\') if OS == :WINDOWS
25
+ File.chmod(0755, @binary) if OS == :LINUX && !File.executable?(@binary)
26
+ @absent_binary = File.join(File.dirname(File.expand_path(__FILE__)), "test_app_absent")
27
+ end
29
28
 
30
- def test_functionality
31
- if OS == :WINDOWS && Sys::Uname.sysname =~ /(Windows 7)/
32
- skip "This test shouldn't be run on #{$1}"
33
- end
29
+ def test_functionality
30
+ if OS == :WINDOWS && Sys::Uname.sysname =~ /(Windows 7)/
31
+ skip "This test shouldn't be run on #{$1}"
32
+ end
34
33
 
35
- # test start
36
- # test application should actually start here
37
- assert_nothing_raised{ RunInBackground.start(@binary, ["1000"], @good_daemon) }
38
- assert_raise(ArgumentError) { RunInBackground.start(@absent_binary, ["1000"], @bad_daemon) }
34
+ # test start
35
+ # test application should actually start here
36
+ assert_nothing_raised{ RunInBackground.start(@binary, ["1000"], @good_daemon) }
37
+ assert_raise(ArgumentError) { RunInBackground.start(@absent_binary, ["1000"], @bad_daemon) }
39
38
 
40
- # start arguments have to be defined
41
- assert_raise(ArgumentError) { RunInBackground.start(["1000"], @bad_daemon) }
42
- assert_raise(ArgumentError) { RunInBackground.start(nil, ["1000"], @bad_daemon) }
43
- assert_raise(ArgumentError) { RunInBackground.start(@absent_binary, nil, @bad_daemon) }
44
- assert_raise(ArgumentError) { RunInBackground.start(@absent_binary, ["1000"], nil) }
39
+ # start arguments have to be defined
40
+ assert_raise(ArgumentError) { RunInBackground.start(["1000"], @bad_daemon) }
41
+ assert_raise(ArgumentError) { RunInBackground.start(nil, ["1000"], @bad_daemon) }
42
+ assert_raise(ArgumentError) { RunInBackground.start(@absent_binary, nil, @bad_daemon) }
43
+ assert_raise(ArgumentError) { RunInBackground.start(@absent_binary, ["1000"], nil) }
45
44
 
46
- # test exists?
47
- assert_raise(ArgumentError) { RunInBackground.exists? }
48
- assert_equal(false, RunInBackground.exists?(@bad_daemon))
49
- assert_equal(true, RunInBackground.exists?(@good_daemon))
45
+ # test exists?
46
+ assert_raise(ArgumentError) { RunInBackground.exists? }
47
+ assert_equal(false, RunInBackground.exists?(@bad_daemon))
48
+ assert_equal(true, RunInBackground.exists?(@good_daemon))
50
49
 
51
- # test running?
52
- # if stop method will be public need to add test checks actually stopped daemon
53
- assert_raise(ArgumentError) { RunInBackground.running? }
54
- assert_raise(ArgumentError) { RunInBackground.running?(@bad_daemon) }
55
- assert_equal(true, RunInBackground.running?(@good_daemon))
50
+ # test running?
51
+ # if stop method will be public need to add test checks actually stopped daemon
52
+ assert_raise(ArgumentError) { RunInBackground.running? }
53
+ assert_raise(ArgumentError) { RunInBackground.running?(@bad_daemon) }
54
+ assert_equal(true, RunInBackground.running?(@good_daemon))
56
55
 
57
- # test daemonazing (start!)
58
- # from the nature of daemonization need to run it from another process that will be daemonized
59
- ruby = (OS == :WINDOWS ? RunInBackground::RUBY_INTERPRETER_PATH : "ruby")
60
- cmd = "#{ruby} -Ilib #{@binary} 50 #{@good_daemonize}"
61
- pid = spawn(cmd)
62
- Process.waitpid pid
63
- # checking that it indeed was daemonized
64
- # e.i. process was killed and code rerun in background
65
- # it takes time to the OS to remove process, so using a timeout here
66
- 0.upto(RunInBackground::TIMEOUT) do
67
- begin
68
- Process.kill(0, pid)
69
- rescue Errno::ESRCH
70
- break
71
- end
72
- sleep 1
56
+ # test daemonazing (start!)
57
+ # from the nature of daemonization need to run it from another process that will be daemonized
58
+ ruby = (OS == :WINDOWS ? RunInBackground::RUBY_INTERPRETER_PATH : "ruby")
59
+ cmd = "#{ruby} -Ilib #{@binary} 50 #{@good_daemonize}"
60
+ pid = spawn(cmd)
61
+ Process.waitpid pid
62
+ # checking that it indeed was daemonized
63
+ # e.i. process was killed and code rerun in background
64
+ # it takes time to the OS to remove process, so using a timeout here
65
+ 0.upto(RunInBackground::TIMEOUT) do
66
+ begin
67
+ Process.kill(0, pid)
68
+ rescue Errno::ESRCH
69
+ break
73
70
  end
74
- assert_raise(Errno::ESRCH) { Process.kill(0, pid) }
75
- assert_equal(true, RunInBackground.exists?(@good_daemonize))
76
- assert_equal(true, RunInBackground.running?(@good_daemonize))
71
+ sleep 1
72
+ end
73
+ assert_raise(Errno::ESRCH) { Process.kill(0, pid) }
74
+ assert_equal(true, RunInBackground.exists?(@good_daemonize))
75
+ assert_equal(true, RunInBackground.running?(@good_daemonize))
77
76
 
78
- # test running win32 specific daemon (start_win32service)
79
- # wrapper script will be run
80
- if OS == :WINDOWS
81
- win32service_arg = [RunInBackground::RUBY_INTERPRETER_PATH, @binary, 1000]
82
- assert_nothing_raised{
83
- RunInBackground.start_win32service(RunInBackground::WRAPPER_SCRIPT,
84
- win32service_arg, @good_win32daemon)
85
- }
86
- assert_equal(true, RunInBackground.exists?(@good_win32daemon))
87
- assert_equal(true, RunInBackground.running?(@good_win32daemon))
88
- else
89
- assert_raise(NotImplementedError) {
90
- RunInBackground.start_win32service(@absent_binary, [], @bad_daemon)
91
- }
92
- end
77
+ # test running win32 specific daemon (start_win32service)
78
+ # wrapper script will be run
79
+ if OS == :WINDOWS
80
+ win32service_arg = [RunInBackground::RUBY_INTERPRETER_PATH, @binary, 1000]
81
+ assert_nothing_raised{
82
+ RunInBackground.start_win32service(RunInBackground::WRAPPER_SCRIPT,
83
+ win32service_arg, @good_win32daemon)
84
+ }
85
+ assert_equal(true, RunInBackground.exists?(@good_win32daemon))
86
+ assert_equal(true, RunInBackground.running?(@good_win32daemon))
87
+ else
88
+ assert_raise(NotImplementedError) {
89
+ RunInBackground.start_win32service(@absent_binary, [], @bad_daemon)
90
+ }
91
+ end
93
92
 
94
- # uncomment following lines if there is a suspicion that something gone wrong
95
- # inspired by bug caused by coworking of daemon_wrapper an logger
96
- #sleep 10
97
- #assert_equal(true, RunInBackground.running?(@good_daemon))
98
- #assert_equal(true, RunInBackground.running?(@good_daemonize))
99
- #assert_equal(true, RunInBackground.running?(@good_win32daemon))
93
+ # uncomment following lines if there is a suspicion that something gone wrong
94
+ # inspired by bug caused by coworking of daemon_wrapper an logger
95
+ #sleep 10
96
+ #assert_equal(true, RunInBackground.running?(@good_daemon))
97
+ #assert_equal(true, RunInBackground.running?(@good_daemonize))
98
+ #assert_equal(true, RunInBackground.running?(@good_win32daemon))
100
99
 
101
- # test delete
102
- # test application should actually stop here
103
- assert_raise(ArgumentError) { RunInBackground.delete }
104
- assert_raise(ArgumentError) { RunInBackground.delete(@bad_daemon) }
105
- assert_nothing_raised { RunInBackground.delete(@good_daemon) }
106
- assert_equal(false, RunInBackground.exists?(@good_daemon))
100
+ # test delete
101
+ # test application should actually stop here
102
+ assert_raise(ArgumentError) { RunInBackground.delete }
103
+ assert_raise(ArgumentError) { RunInBackground.delete(@bad_daemon) }
104
+ assert_nothing_raised { RunInBackground.delete(@good_daemon) }
105
+ assert_equal(false, RunInBackground.exists?(@good_daemon))
107
106
 
108
- assert_nothing_raised { RunInBackground.delete(@good_daemonize) }
109
- assert_equal(false, RunInBackground.exists?(@good_daemonize))
107
+ assert_nothing_raised { RunInBackground.delete(@good_daemonize) }
108
+ assert_equal(false, RunInBackground.exists?(@good_daemonize))
110
109
 
111
- # actuall only for Windows platform
112
- if RunInBackground.exists?(@good_win32daemon)
113
- assert_nothing_raised { RunInBackground.delete(@good_win32daemon) }
114
- assert_equal(false, RunInBackground.exists?(@good_win32daemon))
115
- end
110
+ # actuall only for Windows platform
111
+ if RunInBackground.exists?(@good_win32daemon)
112
+ assert_nothing_raised { RunInBackground.delete(@good_win32daemon) }
113
+ assert_equal(false, RunInBackground.exists?(@good_win32daemon))
116
114
  end
115
+ end
117
116
 
118
- def teardown
119
- RunInBackground.delete @good_daemon if RunInBackground.exists? @good_daemon
120
- RunInBackground.delete @good_daemonize if RunInBackground.exists? @good_daemonize
121
- RunInBackground.delete @good_win32daemon if RunInBackground.exists? @good_win32daemon
122
- end
117
+ def teardown
118
+ RunInBackground.delete @good_daemon if RunInBackground.exists? @good_daemon
119
+ RunInBackground.delete @good_daemonize if RunInBackground.exists? @good_daemonize
120
+ RunInBackground.delete @good_win32daemon if RunInBackground.exists? @good_win32daemon
123
121
  end
124
122
  end
@@ -18,12 +18,12 @@ begin
18
18
 
19
19
  # On WindowsXP log can be found under:
20
20
  # C:/Documents and Settings/NetworkService/.bbfs/test_app_<pid>.log
21
- BBFS::Params['log_file_name'] = File.join(Dir.home, '.bbfs', "#{File.basename(__FILE__)}_#{Process.pid}.log")
22
- BBFS::Params['log_write_to_console'] = false
23
- BBFS::Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] = 1
21
+ Params['log_file_name'] = File.join(Dir.home, '.bbfs', "#{File.basename(__FILE__)}_#{Process.pid}.log")
22
+ Params['log_write_to_console'] = false
23
+ Params['log_param_max_elapsed_time_in_seconds_from_last_flush'] = 1
24
24
  if DBG
25
- BBFS::Params['log_debug_level'] = 1
26
- BBFS::Log.init
25
+ Params['log_debug_level'] = 1
26
+ Log.init
27
27
  end
28
28
 
29
29
  # app should be run in background
@@ -36,23 +36,23 @@ begin
36
36
  require 'run_in_background'
37
37
  end
38
38
 
39
- BBFS::Log.debug1 "Before run in background: PID #{Process.pid}"
39
+ Log.debug1 "Before run in background: PID #{Process.pid}"
40
40
  # ARGV.pop returns frozen string and thus causes a failure of Service.create
41
41
  # to fix it new string with the same content created.
42
- BBFS::RunInBackground.start!(String.new(ARGV.pop))
42
+ RunInBackground.start!(String.new(ARGV.pop))
43
43
  # if got here then error
44
- BBFS::Log.error "After run in background: ERROR"
44
+ Log.error "After run in background: ERROR"
45
45
  end
46
46
 
47
47
  max = (ARGV.size > 0 && ARGV[0] != nil && ARGV[0].to_i > 0)? ARGV[0].to_i : 200
48
48
 
49
49
  while max > 0
50
- BBFS::Log.debug1 "#{max}"
50
+ Log.debug1 "#{max}"
51
51
  sleep 1
52
52
  max -= 1
53
53
  end
54
54
 
55
55
  rescue Exception => err
56
- BBFS::Log.error "Wrapper error: #{err}"
56
+ Log.error "Wrapper error: #{err}"
57
57
  raise
58
58
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: run_in_background
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-02 00:00:00.000000000 Z
12
+ date: 2013-05-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: log
@@ -58,7 +58,7 @@ files:
58
58
  - test/run_in_background/test_app
59
59
  - test/run_in_background/run_in_background_test.rb
60
60
  - ext/run_in_background/mkrf_conf.rb
61
- homepage: http://github.com/kolmanv/bbfs
61
+ homepage: http://github.com/bbfsdev/bbfs
62
62
  licenses: []
63
63
  post_install_message:
64
64
  rdoc_options: []