Class: Bannister::Apache

Inherits:
Object
  • Object
show all
Defined in:
lib/bannister/apache.rb

Overview

A standardised apache launcher.

Constant Summary collapse

PidFilename =

Location of apache’s pidfile. This must agree with apache.conf.

"tmp/apache2.pid"

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Apache

Returns a new instance of Apache.

Parameters:

  • config (Hash)

    A config hash to be merged with ENV for substitution into apache.conf.

Raises:

  • (ArgumentError)


11
12
13
14
15
# File 'lib/bannister/apache.rb', line 11

def initialize(config)
  raise ArgumentError.new("config cannot be nil") if config.nil?

  @config = config
end

Instance Method Details

#start(foreground = false) ⇒ Object

Start apache, then sleep. If foreground is true, then pass the -X option to apache. This makes it run in the foreground.

Before sleeping, trap TERM and HUP so that we can signal apache to stop. We need to do this so that when screen exits, we can tell apache to exit instead of restart, which is its usual HUP response.

Parameters:

  • foreground (Boolean) (defaults to: false)

    Set true to run in the foreground.



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
76
77
78
79
80
81
# File 'lib/bannister/apache.rb', line 50

def start(foreground=false)
  @apache2_conf = @config['Apache2Conf']
  rewrite_envvars(ENV)
  system "mkdir -p tmp"
  cmd = foreground ? "/usr/sbin/apache2 -f #{@apache2_conf} -X &" :
  "/usr/sbin/apache2 -f #{@apache2_conf}" 
  if system( cmd )
    # runner sends TERM, but screen sends a HUP when it quits.
    # This is why we can't just exec apache -X; apache restarts
    # on HUP.
    trap("TERM"){ stop() }
    trap("HUP"){ stop() }

    # Apache2's pidfile is written by the child process
    # after the parent process (the one we kick off) terminates.
    # This means that we need to wait for it.
    catch :done do
      20.times do
        sleep(0.1)
        next if !File.file?(PidFilename)
        throw :done
      end
      raise "Apache2 failed to write #{PidFilename}"
    end

    sleep # Sleep to wait for the TERM signal

  else
    raise "Apache2 failed to start!"
  end

end

#stopObject

Send a TERM signal to the apache process. If the process is still running after 2 seconds, a RuntimeError is thrown.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/bannister/apache.rb', line 21

def stop
  if pid = read_pid()
    Process.kill("TERM", pid)
    # the apache process isn't a child process, so we can't
    # use Process.waitpid. Instead we use kill -0, which tests
    # whether we can send the given pid a signal.
    catch :done do
      20.times do
        sleep(0.1)
        # No need to trap error messages here, because `kill`
        # gives us a meaningful error code
        next if system "kill -0 #{pid} 2> /dev/null"
        throw :done
      end
      
      raise "Apache2 (pid=#{pid}) failed to stop!"
    end
  end
end