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