Module: Pigeon::Support

Extended by:
Support
Included in:
Support
Defined in:
lib/pigeon/support.rb

Instance Method Summary collapse

Instance Method Details

#daemonize(logger = nil) ⇒ Object

Uses the double-fork method to create a fully detached background process. Returns the process ID of the created process. May throw an exception if these processes could not be created.



7
8
9
10
11
12
13
14
15
16
17
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/pigeon/support.rb', line 7

def daemonize(logger = nil)
  delay = 10
  rfd, wfd = IO.pipe
  
  forked_pid = fork do
    rfd.close

    supervisor_pid = fork do
      relaunch = true
      
      while (relaunch)
        daemon_pid = fork do
          begin
            yield
          rescue Object => e
            if (logger)
              logger.error("Terminated with Exception: [#{e.class}] #{e}")
              logger.error(e.backtrace.join("\n"))

              Thread.list.each do |thread|
                logger.error("Stack trace of current threads")
                logger.error(thread.inspect)
                
                if (thread.backtrace)
                  logger.error("\t" + thread.backtrace.join("\n\t"))
                end
                
              end
            end

            exit(-1)
          end
        end

        begin
          Process.wait(daemon_pid)

          # A non-zero exit status indicates some sort of error, so the
          # process will be relaunched after a short delay.
          relaunch = ($? != 0)

        rescue Interrupt
          Process.kill('INT', daemon_pid)

          relaunch = false
        end
        
        if (relaunch)
          logger.info("Will relaunch in %d seconds" % delay)

          sleep(delay)
        else
          logger.info("Terminated normally")
        end
      end
    end

    wfd.puts(supervisor_pid)
    wfd.flush
    wfd.close
  end

  Process.wait(forked_pid)

  daemon_pid = rfd.readline
  rfd.close
  
  daemon_pid.to_i
end

#find_writable_directory(*list) ⇒ Object

Finds the first directory in the given list that exists and is writable. Returns nil if none match.



79
80
81
82
83
# File 'lib/pigeon/support.rb', line 79

def find_writable_directory(*list)
  list.flatten.compact.find do |dir|
    File.exist?(dir) and File.writable?(dir)
  end
end

#unique_idObject

Returns a unique 160-bit identifier for this engine expressed as a 40 character hexadecimal string. The first 32-bit sequence is a timestamp so these numbers increase over time and can be used to identify when a particular instance was launched. For informational purposes, the name of the host is appended to help identify the origin of the ident.



90
91
92
93
94
95
96
97
98
# File 'lib/pigeon/support.rb', line 90

def unique_id
  '%8x%s@%s' % [
    Time.now.to_i,
    Digest::SHA1.hexdigest(
      '%.8f%8x' % [ Time.now.to_f, rand(1 << 32) ]
    )[0, 32],
    Socket.gethostname
  ]
end