lib/service_manager/service.rb in service_manager-0.4 vs lib/service_manager/service.rb in service_manager-0.5

- old
+ new

@@ -1,11 +1,13 @@ +require "thread" class ServiceManager::Service + CHDIR_SEMAPHORE = Mutex.new NORMAL_COLOR = 37 attr_accessor :name, :host, :port, :cwd, :reload_uri, :start_cmd, :process, :loaded_cue, :timeout, :color - class ServerDidntStart < Exception; end + class ServiceDidntStart < Exception; end def initialize(options = {}) options.each { |k,v| send("#{k}=", v) } self.host ||= "localhost" self.color ||= NORMAL_COLOR @@ -49,21 +51,24 @@ reload || puts("Reloading not supported. Any changes made to code for #{colorized_service_name} will not take effect!") return false end puts "Starting #{colorized_service_name} in #{cwd} with '#{start_cmd}'" - Dir.chdir(cwd) do - without_bundler_env do - # system("bash -c set") - self.process = PTYBackgroundProcess.run(start_cmd) + CHDIR_SEMAPHORE.synchronize do + 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." end + # stop the service. If we didn't start it, do nothing. def stop return unless process puts "Shutting down #{colorized_service_name}" process.kill process.wait(3) @@ -74,18 +79,20 @@ puts "Server #{colorized_service_name} (#{process.pid}) is shut down" self.process = nil true end + # 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. 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 + # detects if the service is running on the configured host and port (will return true if we weren't the ones who started it) def running? TCPSocket.listening_service?(:port => port, :host => host) end protected @@ -101,17 +108,17 @@ end end def wait if loaded_cue - raise(ServerDidntStart) unless watch_for_cue + raise(ServiceDidntStart) unless watch_for_cue start_output_stream_thread else start_output_stream_thread begin TCPSocket.wait_for_service_with_timeout({:host => host, :port => port, :timeout => timeout}) rescue SocketError - raise ServerDidntStart + raise ServiceDidntStart end end true end end