Class: ServiceManager::Service
- Inherits:
-
Object
- Object
- ServiceManager::Service
- Defined in:
- lib/service_manager/service.rb
Defined Under Namespace
Classes: ServiceDidntStart
Constant Summary collapse
- CHDIR_SEMAPHORE =
Mutex.new
- ANSI_COLOR_RESET =
0
Instance Attribute Summary collapse
-
#color ⇒ Object
Returns the value of attribute color.
-
#cwd ⇒ Object
Returns the value of attribute cwd.
-
#host ⇒ Object
Returns the value of attribute host.
-
#loaded_cue ⇒ Object
Returns the value of attribute loaded_cue.
-
#manage_pid_file ⇒ Object
Returns the value of attribute manage_pid_file.
-
#name ⇒ Object
Returns the value of attribute name.
-
#pid_file ⇒ Object
Returns the value of attribute pid_file.
-
#port ⇒ Object
Returns the value of attribute port.
-
#process ⇒ Object
Returns the value of attribute process.
-
#reload_uri ⇒ Object
Returns the value of attribute reload_uri.
-
#start_cmd ⇒ Object
Returns the value of attribute start_cmd.
-
#timeout ⇒ Object
Returns the value of attribute timeout.
Instance Method Summary collapse
-
#initialize(options = {}) ⇒ Service
constructor
A new instance of Service.
-
#reload ⇒ Object
reload the service by hitting the configured reload_url.
-
#running? ⇒ Boolean
detects if the service is running on the configured host and port (will return true if we weren’t the ones who started it).
- #server_info_hash ⇒ Object
- #start ⇒ Object
- #start_output_stream_thread ⇒ Object
-
#stop ⇒ Object
stop the service.
- #url ⇒ Object
- #watch_for_cue ⇒ Object
- #without_bundler_env(&block) ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Service
Returns a new instance of Service.
11 12 13 14 15 16 17 |
# File 'lib/service_manager/service.rb', line 11 def initialize( = {}) .each { |k,v| send("#{k}=", v) } self.host ||= "localhost" self.color ||= ANSI_COLOR_RESET self.timeout ||= 30 raise ArgumentError, "You need to provide a name for this app service" unless name end |
Instance Attribute Details
#color ⇒ Object
Returns the value of attribute color.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def color @color end |
#cwd ⇒ Object
Returns the value of attribute cwd.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def cwd @cwd end |
#host ⇒ Object
Returns the value of attribute host.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def host @host end |
#loaded_cue ⇒ Object
Returns the value of attribute loaded_cue.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def loaded_cue @loaded_cue end |
#manage_pid_file ⇒ Object
Returns the value of attribute manage_pid_file.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def manage_pid_file @manage_pid_file end |
#name ⇒ Object
Returns the value of attribute name.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def name @name end |
#pid_file ⇒ Object
Returns the value of attribute pid_file.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def pid_file @pid_file end |
#port ⇒ Object
Returns the value of attribute port.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def port @port end |
#process ⇒ Object
Returns the value of attribute process.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def process @process end |
#reload_uri ⇒ Object
Returns the value of attribute reload_uri.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def reload_uri @reload_uri end |
#start_cmd ⇒ Object
Returns the value of attribute start_cmd.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def start_cmd @start_cmd end |
#timeout ⇒ Object
Returns the value of attribute timeout.
7 8 9 |
# File 'lib/service_manager/service.rb', line 7 def timeout @timeout end |
Instance Method Details
#reload ⇒ Object
reload the service by hitting the configured reload_url. In this case, the service needs to be a web service, and needs to have an action that you can hit, in test mode, that will cause the process to gracefully reload itself.
88 89 90 91 92 93 94 |
# File 'lib/service_manager/service.rb', line 88 def reload return false unless reload_uri puts "Reloading #{colorized_service_name} app by hitting http://#{host}:#{port}#{reload_uri} ..." res = Net::HTTP.start(host, port) {|http| http.get(reload_uri) } raise("Reloading app #{colorized_service_name} did not return a 200! It returned a #{res.code}. Output:\n#{colorize(res.body)}") unless res.code.to_i == 200 true end |
#running? ⇒ Boolean
detects if the service is running on the configured host and port (will return true if we weren’t the ones who started it)
97 98 99 100 101 102 103 104 105 |
# File 'lib/service_manager/service.rb', line 97 def running? case when pid_file running_via_pid_file? when port TCPSocket.listening_service?(:port => port, :host => host || "127.0.0.1") else raise "Service Manager needs to be able to tell if the service is already running or not. You'll need to specify a pid file or a TCP port to check." end end |
#server_info_hash ⇒ Object
23 24 25 |
# File 'lib/service_manager/service.rb', line 23 def server_info_hash {:name => name, :host => host, :port => port, :pid_file => pid_file} end |
#start ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/service_manager/service.rb', line 49 def start if running? puts "Server for #{colorized_service_name} detected as running." reload || puts("Reloading not supported. Any changes made to code for #{colorized_service_name} will not take effect!") return false end CHDIR_SEMAPHORE.synchronize do puts "Starting #{colorized_service_name} in #{cwd} with '#{start_cmd}'\n" Dir.chdir(cwd) do without_bundler_env do # system("bash -c set") self.process = PTYBackgroundProcess.run(start_cmd) end end end at_exit { stop } wait puts "Server #{colorized_service_name} is up." File.open(pid_file, "wb") { |f| f << process.pid } if manage_pid_file end |
#start_output_stream_thread ⇒ Object
34 35 36 |
# File 'lib/service_manager/service.rb', line 34 def start_output_stream_thread Thread.new { process.detect { |output| STDOUT << colorize(output); nil} } end |
#stop ⇒ Object
stop the service. If we didn’t start it, do nothing.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/service_manager/service.rb', line 72 def stop return unless process puts "Shutting down #{colorized_service_name}" process.kill process.wait(3) if process.running? process.kill("KILL") # ok... no more Mr. Nice Guy. process.wait end puts "Server #{colorized_service_name} (#{process.pid}) is shut down" self.process = nil FileUtils.rm(pid_file) if manage_pid_file && File.exist?(pid_file) true end |
#url ⇒ Object
19 20 21 |
# File 'lib/service_manager/service.rb', line 19 def url "http://#{host}:#{port}" end |
#watch_for_cue ⇒ Object
27 28 29 30 31 32 |
# File 'lib/service_manager/service.rb', line 27 def watch_for_cue process.detect(:both, timeout) do |output| STDOUT << colorize(output) output =~ loaded_cue end end |
#without_bundler_env(&block) ⇒ Object
42 43 44 45 46 47 |
# File 'lib/service_manager/service.rb', line 42 def without_bundler_env(&block) vars = %w{BUNDLE_PATH BUNDLE_GEMFILE BUNDLE_BIN_PATH} old_values = vars.map {|v| ENV.delete(v)} yield vars.zip(old_values).each { |var, value| ENV[var] = value } end |