Class: Expedite::Server::AgentManager

Inherits:
Object
  • Object
show all
Defined in:
lib/expedite/server/agent_manager.rb

Overview

Locates agent processes and spawns them if necessary

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, env) ⇒ AgentManager

Returns a new instance of AgentManager.



14
15
16
17
18
19
20
21
22
# File 'lib/expedite/server/agent_manager.rb', line 14

def initialize(name, env)
  @name  = name.to_s
  @env   = env
  @mutex = Mutex.new
  @state = :running
  @pid   = nil

  @agent = Expedite::Agents.lookup(@name)
end

Instance Attribute Details

#agentObject (readonly)

Returns the value of attribute agent.



12
13
14
# File 'lib/expedite/server/agent_manager.rb', line 12

def agent
  @agent
end

#childObject (readonly)

Returns the value of attribute child.



12
13
14
# File 'lib/expedite/server/agent_manager.rb', line 12

def child
  @child
end

#envObject (readonly)

Returns the value of attribute env.



12
13
14
# File 'lib/expedite/server/agent_manager.rb', line 12

def env
  @env
end

#nameObject (readonly)

Returns the value of attribute name.



12
13
14
# File 'lib/expedite/server/agent_manager.rb', line 12

def name
  @name
end

#pidObject (readonly)

Returns the value of attribute pid.



12
13
14
# File 'lib/expedite/server/agent_manager.rb', line 12

def pid
  @pid
end

#statusObject (readonly)

Returns the value of attribute status.



12
13
14
# File 'lib/expedite/server/agent_manager.rb', line 12

def status
  @status
end

Instance Method Details

#alive?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/expedite/server/agent_manager.rb', line 46

def alive?
  @pid
end

#keep_aliveObject



107
108
109
# File 'lib/expedite/server/agent_manager.rb', line 107

def keep_alive
  agent.keep_alive
end

#log(message) ⇒ Object



24
25
26
# File 'lib/expedite/server/agent_manager.rb', line 24

def log(message)
  env.log "[application_manager:#{name}] #{message}"
end

#parentObject



111
112
113
# File 'lib/expedite/server/agent_manager.rb', line 111

def parent
  agent.parent
end

#restartObject



41
42
43
44
# File 'lib/expedite/server/agent_manager.rb', line 41

def restart
  return if @state == :stopping
  start_child(true)
end

#run(client) ⇒ Object

Returns the pid of the process running the command, or nil if the application process died.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/expedite/server/agent_manager.rb', line 71

def run(client)
  with_child do |child|
    child.send_io client
    child.gets or raise Errno::EPIPE
  end

  pid = child.gets.to_i

  unless pid.zero?
    log "got worker pid #{pid}"
    pid
  end
rescue Exception => e
  # NotImplementedError is an Exception, not StandardError
  client.send_exception(e, env)
  return Process.pid
rescue Errno::ECONNRESET, Errno::EPIPE => e
  log "#{e} while reading from child; returning no pid"
  nil
ensure
  client.close
end

#startObject



37
38
39
# File 'lib/expedite/server/agent_manager.rb', line 37

def start
  start_child
end

#stopObject



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/expedite/server/agent_manager.rb', line 94

def stop
  log "stopping"
  @state = :stopping

  _pid = self.pid
  if _pid
    Process.kill('TERM', _pid)
    Process.wait(_pid)
  end
rescue Errno::ESRCH, Errno::ECHILD
  # Don't care
end

#synchronizeObject

We’re not using @mutex.synchronize to avoid the weird “<internal:prelude>:10” line which messes with backtraces in e.g. rspec



30
31
32
33
34
35
# File 'lib/expedite/server/agent_manager.rb', line 30

def synchronize
  @mutex.lock
  yield
ensure
  @mutex.unlock
end

#with_childObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/expedite/server/agent_manager.rb', line 50

def with_child
  synchronize do
    if alive?
      begin
        yield child
      rescue Errno::ECONNRESET, Errno::EPIPE
        # The child has died but has not been collected by the wait thread yet,
        # so start a new child and try again.
        log "child dead; starting"
        start
        yield child
      end
    else
      log "child not running; starting"
      start
      yield child
    end
  end
end