Class: ServiceManager::Service

Inherits:
Object
  • Object
show all
Defined in:
lib/service_manager/service.rb

Defined Under Namespace

Classes: ServiceDidntStart

Constant Summary collapse

CHDIR_SEMAPHORE =
Mutex.new
NORMAL_COLOR =
37

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Service

Returns a new instance of Service.

Raises:

  • (ArgumentError)


10
11
12
13
14
15
16
# File 'lib/service_manager/service.rb', line 10

def initialize(options = {})
  options.each { |k,v| send("#{k}=", v) }
  self.host ||= "localhost"
  self.color ||= NORMAL_COLOR
  self.timeout ||= 30
  raise ArgumentError, "You need to provide a name for this app service" unless name
end

Instance Attribute Details

#colorObject

Returns the value of attribute color.



6
7
8
# File 'lib/service_manager/service.rb', line 6

def color
  @color
end

#cwdObject

Returns the value of attribute cwd.



6
7
8
# File 'lib/service_manager/service.rb', line 6

def cwd
  @cwd
end

#hostObject

Returns the value of attribute host.



6
7
8
# File 'lib/service_manager/service.rb', line 6

def host
  @host
end

#loaded_cueObject

Returns the value of attribute loaded_cue.



6
7
8
# File 'lib/service_manager/service.rb', line 6

def loaded_cue
  @loaded_cue
end

#nameObject

Returns the value of attribute name.



6
7
8
# File 'lib/service_manager/service.rb', line 6

def name
  @name
end

#portObject

Returns the value of attribute port.



6
7
8
# File 'lib/service_manager/service.rb', line 6

def port
  @port
end

#processObject

Returns the value of attribute process.



6
7
8
# File 'lib/service_manager/service.rb', line 6

def process
  @process
end

#reload_uriObject

Returns the value of attribute reload_uri.



6
7
8
# File 'lib/service_manager/service.rb', line 6

def reload_uri
  @reload_uri
end

#start_cmdObject

Returns the value of attribute start_cmd.



6
7
8
# File 'lib/service_manager/service.rb', line 6

def start_cmd
  @start_cmd
end

#timeoutObject

Returns the value of attribute timeout.



6
7
8
# File 'lib/service_manager/service.rb', line 6

def timeout
  @timeout
end

Instance Method Details

#reloadObject

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.



85
86
87
88
89
90
91
# File 'lib/service_manager/service.rb', line 85

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)

Returns:

  • (Boolean)


94
95
96
# File 'lib/service_manager/service.rb', line 94

def running?
  TCPSocket.listening_service?(:port => port, :host => host)
end

#server_info_hashObject



22
23
24
# File 'lib/service_manager/service.rb', line 22

def server_info_hash
  {:name => name, :host => host, :port => port}
end

#startObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/service_manager/service.rb', line 48

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

  puts "Starting #{colorized_service_name} in #{cwd} with '#{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

#start_output_stream_threadObject



33
34
35
# File 'lib/service_manager/service.rb', line 33

def start_output_stream_thread
  Thread.new { process.detect { |output| STDOUT << colorize(output); nil} }
end

#stopObject

stop the service. If we didn’t start it, do nothing.



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/service_manager/service.rb', line 70

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
  true
end

#urlObject



18
19
20
# File 'lib/service_manager/service.rb', line 18

def url
  "http://#{host}:#{port}"
end

#watch_for_cueObject



26
27
28
29
30
31
# File 'lib/service_manager/service.rb', line 26

def watch_for_cue
  process.detect(:both, timeout) do |output|
    STDOUT << colorize(output)
    output =~ loaded_cue
  end
end

#without_bundler_env(&block) ⇒ Object



41
42
43
44
45
46
# File 'lib/service_manager/service.rb', line 41

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