Module: ActsAsService::ClassMethods
- Defined in:
- lib/acts_as_service.rb
Instance Method Summary collapse
-
#_display_name ⇒ Object
fetches the service’s name, using class name as default —————————————————————————.
-
#_pid ⇒ Object
the current process’ pid —————————————————————————.
-
#_pid_file_content ⇒ Object
returns the entire contents of the pid file —————————————————————————.
-
#_pid_file_exists? ⇒ Boolean
indicates if the pid file exists for this service —————————————————————————.
-
#_pid_file_pid ⇒ Object
the pid found in the pidfile (if it exists, nil if it doesn’t) —————————————————————————.
-
#_pid_file_process_running? ⇒ Boolean
Checks to see if the process pointed to by the pid file is actually running Note that I couldn’t find a good way to check for the status of a different process by its pid, so this checks to see if the proces has a process group id, and if the process doesn’t exist, an exception is returned —————————————————————————.
-
#_pid_filename ⇒ Object
returns the pid filename —————————————————————————.
-
#_process_running? ⇒ Boolean
returns true if the current process is the pid in the pid file.
-
#_shutting_down? ⇒ Boolean
returns true if the service is in the process of shutting down.
-
#_status ⇒ Object
the current status of the service.
-
#restart ⇒ Object
stops the current service process and runs a new one in the current process —————————————————————————–.
-
#service_pid ⇒ Object
method for outside consumption of the pid value.
-
#service_running? ⇒ Boolean
method for outside consumption of status info.
-
#shutdown ⇒ Object
initiate shutdown.
-
#start ⇒ Object
starts the process if it’s not already running —————————————————————————.
-
#stop ⇒ Object
stops the process if it’s running —————————————————————————.
Instance Method Details
#_display_name ⇒ Object
fetches the service’s name, using class name as default
199 200 201 |
# File 'lib/acts_as_service.rb', line 199 def _display_name respond_to?(:service_name) ? service_name : name.split("::").last end |
#_pid ⇒ Object
the current process’ pid
277 278 279 |
# File 'lib/acts_as_service.rb', line 277 def _pid @@_pid ||= Process.pid end |
#_pid_file_content ⇒ Object
returns the entire contents of the pid file
257 258 259 260 261 262 263 264 |
# File 'lib/acts_as_service.rb', line 257 def _pid_file_content begin f = File.open(_pid_filename, 'r') return f.blank? ? f : f.read rescue Errno::ENOENT return nil end end |
#_pid_file_exists? ⇒ Boolean
indicates if the pid file exists for this service
250 251 252 |
# File 'lib/acts_as_service.rb', line 250 def _pid_file_exists? File.exist?(_pid_filename) end |
#_pid_file_pid ⇒ Object
the pid found in the pidfile (if it exists, nil if it doesn’t)
269 270 271 272 |
# File 'lib/acts_as_service.rb', line 269 def _pid_file_pid /^(\d*)$/ =~ _pid_file_content return $1.blank? ? nil : $1.to_i end |
#_pid_file_process_running? ⇒ Boolean
Checks to see if the process pointed to by the pid file is actually running Note that I couldn’t find a good way to check for the status of a different process by its pid, so this checks to see if the proces has a process group id, and if the process doesn’t exist, an exception is returned
288 289 290 291 292 293 294 295 |
# File 'lib/acts_as_service.rb', line 288 def _pid_file_process_running? begin Process.getpgid(_pid_file_pid) return true rescue return false end end |
#_pid_filename ⇒ Object
returns the pid filename
206 207 208 209 210 211 212 213 |
# File 'lib/acts_as_service.rb', line 206 def _pid_filename if respond_to?(:service_pid_filename) return service_pid_filename else return File.join(RAILS_ROOT, 'tmp', 'pids', "#{_display_name.underscore.gsub(/\s+/, '_')}.pid") end end |
#_process_running? ⇒ Boolean
returns true if the current process is the pid in the pid file. false otherwise
301 302 303 |
# File 'lib/acts_as_service.rb', line 301 def _process_running? return _pid == _pid_file_pid end |
#_shutting_down? ⇒ Boolean
returns true if the service is in the process of shutting down. let subclasses access if they’d like
309 310 311 |
# File 'lib/acts_as_service.rb', line 309 def _shutting_down? ACTS_AS_SERVICE_SHUTTING_DOWN == _status end |
#_status ⇒ Object
the current status of the service. possible values:
ACTS_AS_SERVICE_STOPPED : no service process is running
ACTS_AS_SERVICE_SHUTTING_DOWN : process currently shutting down
ACTS_AS_SERVICE_RUNNING : the current process is the service process
ACTS_AS_SERVICE_OTHER_RUNNING : another pid is running the service
ACTS_AS_SERVICE_PID_NO_PROCESS : pidfile exists, but no process running
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/acts_as_service.rb', line 223 def _status _status = nil # logic: # if the pid file doesn't exist, it's stopped # otherwise, if 'shutting down', it's shutting down # or if the pidfile's pid is running, another process is running # or if the pidfile's pid matches this process, it's running # otherwise, the pidfile's there but no one's running if !_pid_file_exists? _status = ACTS_AS_SERVICE_STOPPED elsif Regexp.new(ACTS_AS_SERVICE_SHUTTING_DOWN) =~ _pid_file_content _status = ACTS_AS_SERVICE_SHUTTING_DOWN elsif _process_running? _status = ACTS_AS_SERVICE_RUNNING elsif _pid_file_process_running? _status = ACTS_AS_SERVICE_OTHER_RUNNING else _status = ACTS_AS_SERVICE_PID_NO_PROCESS end return _status end |
#restart ⇒ Object
stops the current service process and runs a new one in the current process
156 157 158 159 |
# File 'lib/acts_as_service.rb', line 156 def restart stop start end |
#service_pid ⇒ Object
method for outside consumption of the pid value. hopefully not tempting method name for class-writers to conflict with…
187 188 189 |
# File 'lib/acts_as_service.rb', line 187 def service_pid _pid_file_pid end |
#service_running? ⇒ Boolean
method for outside consumption of status info. hopefully not tempting method name for class-writers to conflict with…
179 180 181 |
# File 'lib/acts_as_service.rb', line 179 def service_running? _status == ACTS_AS_SERVICE_RUNNING || _status == ACTS_AS_SERVICE_OTHER_RUNNING end |
#shutdown ⇒ Object
initiate shutdown. call this from within perform_work_chunk if the service’s work is done and it should shut down (makes sense for cronjobs, say)
165 166 167 168 169 170 171 172 173 |
# File 'lib/acts_as_service.rb', line 165 def shutdown if self.respond_to?(:before_stop) before_stop end # change the pid file so the original process sees this 'stop' signal File.open(_pid_filename, 'a') do |f| f.write("\n#{ACTS_AS_SERVICE_SHUTTING_DOWN}") end end |
#start ⇒ Object
starts the process if it’s not already running
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/acts_as_service.rb', line 81 def start begin if _status != ACTS_AS_SERVICE_STOPPED && _status != ACTS_AS_SERVICE_PID_NO_PROCESS puts "#{_display_name} (#{_pid_file_pid}) is already running. Ignoring." else # clean out a stale pid if _status == ACTS_AS_SERVICE_PID_NO_PROCESS puts 'Pid file exists but process is not running. Removing old pid file.' File.delete(_pid_filename) end puts "Starting #{_display_name} (#{_pid})...." puts "Run #{name}.stop to stop\n\n" File.open(_pid_filename, 'w') {|f| f.write(_pid.to_s) } if self.respond_to?(:after_start) after_start end _sleep_till = Time.zone.now - 1 while (_status == ACTS_AS_SERVICE_RUNNING) if Time.zone.now >= _sleep_till perform_work_chunk # only reset sleep till if asked to; otherwise, just perform next # work chunk right away (never change _sleep_till) if self.respond_to?(:sleep_time) _sleep_till = Time.zone.now + self.sleep_time end else _check_time_interval = if self.respond_to? :sleep_check_timeout self.sleep_check_timeout else SLEEP_CHECK_TIMEOUT end sleep [_check_time_interval, _sleep_till - Time.zone.now].min end end puts "Shutting down #{_display_name} (#{_pid})" File.delete(_pid_filename) end # if something happens, dump an error and clean up the pidfile if # it's owned by this process rescue Object => e puts "ERROR: #{e}\n#{e.respond_to?(:backtrace) ? e.backtrace.join("\n ") : ''}" puts "Exiting (#{_pid})\n" if _process_running? File.delete(_pid_filename) end end end |
#stop ⇒ Object
stops the process if it’s running
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/acts_as_service.rb', line 136 def stop if _status == ACTS_AS_SERVICE_STOPPED puts "#{_display_name} is not running" elsif _status == ACTS_AS_SERVICE_PID_NO_PROCESS puts 'Pid file exists but process is not running. Removing old pid file.' File.delete(_pid_filename) else pid_to_stop = _pid_file_pid puts "Stopping #{_display_name} (#{pid_to_stop})...." shutdown while (_status != ACTS_AS_SERVICE_STOPPED) sleep(1) end puts "#{_display_name} (#{pid_to_stop}) stopped\n" end end |