Module: Einhorn::Worker

Defined in:
lib/einhorn/worker.rb

Defined Under Namespace

Classes: WorkerError

Class Method Summary collapse

Class Method Details

.ack(*args) ⇒ Object



29
30
31
32
33
34
# File 'lib/einhorn/worker.rb', line 29

def self.ack(*args)
  begin
    ack!(*args)
  rescue WorkerError
  end
end

.ack!(discovery = :env, arg = nil) ⇒ Object

Call this once your app is up and running in a good state. Arguments:

@discovery: How to discover the master process’s command socket.

:env:        Discover the path from ENV['EINHORN_SOCK_PATH']
:fd:         Just use the file descriptor in ENV['EINHORN_FD'].
             Must run the master with the -b flag. This is mostly
             useful if you don't have a nice library like Einhorn::Worker.
             Then @arg being true causes the FD to be left open after ACK;
             otherwise it is closed.
:direct:     Provide the path to the command socket in @arg.

TODO: add a :fileno option? Easy to implement; not sure if it’d be useful for anything. Maybe if it’s always fd 3, because then the user wouldn’t have to provide an arg.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/einhorn/worker.rb', line 51

def self.ack!(discovery=:env, arg=nil)
  ensure_worker!
  close_after_use = true

  case discovery
  when :env
    socket = ENV['EINHORN_SOCK_PATH']
    client = Einhorn::Client.for_path(socket)
  when :fd
    raise "No EINHORN_FD provided in environment. Did you run einhorn with the -b flag?" unless fd_str = ENV['EINHORN_FD']

    fd = Integer(fd_str)
    client = Einhorn::Client.for_fd(fd)
    close_after_use = false if arg
  when :direct
    socket = arg
    client = Einhorn::Client.for_path(socket)
  else
    raise "Unrecognized socket discovery mechanism: #{discovery.inspect}. Must be one of :filesystem, :argv, or :direct"
  end

  client.command({
      'command' => 'worker:ack',
      'pid' => $$
    })

  client.close if close_after_use
  true
end

.ensure_worker!Object



18
19
20
21
22
23
24
25
26
27
# File 'lib/einhorn/worker.rb', line 18

def self.ensure_worker!
  # Make sure that EINHORN_MASTER_PID is my parent
  if ppid_s = ENV['EINHORN_MASTER_PID']
    ppid = ppid_s.to_i
    raise WorkerError.new("EINHORN_MASTER_PID environment variable is #{ppid_s.inspect}, but my parent's pid is #{Process.ppid.inspect}. This probably means that I am a subprocess of an Einhorn worker, but am not one myself.") unless Process.ppid == ppid
    true
  else
    raise WorkerError.new("No EINHORN_MASTER_PID environment variable set. Are you running your process under Einhorn?") unless Process.ppid == ppid
  end
end

.graceful_shutdown(&blk) ⇒ Object

Call this to handle graceful shutdown requests to your app.



82
83
84
# File 'lib/einhorn/worker.rb', line 82

def self.graceful_shutdown(&blk)
  Signal.trap('USR2', &blk)
end

.is_worker?Boolean

Returns:

  • (Boolean)


8
9
10
11
12
13
14
15
16
# File 'lib/einhorn/worker.rb', line 8

def self.is_worker?
  begin
    ensure_worker!
  rescue WorkerError
    false
  else
    true
  end
end