Module: Yahns::Daemon

Defined in:
lib/yahns/daemon.rb

Overview

:nodoc:

Class Method Summary collapse

Class Method Details

.daemon(yahns_server) ⇒ Object

We don’t do a lot of standard daemonization stuff:

* umask is whatever was set by the parent process at startup
  and can be set in config.ru and config_file, so making it
  0000 and potentially exposing sensitive log data can be bad
  policy.
* don't bother to chdir("/") here since yahns is designed to
  run inside APP_ROOT.  Yahns will also re-chdir() to
  the directory it was started in when being re-executed
  to pickup code changes if the original deployment directory
  is a symlink or otherwise got replaced.


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/yahns/daemon.rb', line 18

def self.daemon(yahns_server)
  $stdin.reopen("/dev/null")

  # We only start a new process group if we're not being reexecuted
  # and inheriting file descriptors from our parent
  if ENV['YAHNS_FD']
    # if we're inheriting, need to ensure this remains true so
    # SIGWINCH works when worker processes are in play
    yahns_server.daemon_pipe = true
  else
    # grandparent - reads pipe, exits when master is ready
    #  \_ parent  - exits immediately ASAP
    #      \_ yahns master - writes to pipe when ready

    # We cannot use Yahns::Sigevent (eventfd) here because we need
    # to detect EOF on unexpected death, not just read/write
    rd, wr = IO.pipe
    rd.close_on_exec = wr.close_on_exec = true
    grandparent = $$
    if fork
      wr.close # grandparent does not write
    else
      rd.close # yahns master does not read
      Process.setsid
      exit if fork # parent dies now
    end

    if grandparent == $$
      # this will block until Server#join runs (or it dies)
      master_pid = (rd.readpartial(16) rescue nil).to_i
      unless master_pid > 1
        warn "master failed to start, check stderr log for details"
        exit!
      end
      exit
    else # yahns master process
      yahns_server.daemon_pipe = wr
    end
  end
  # $stderr/$stderr can/will be redirected separately in the Yahns config
end