Class: RailsFCGIHandler

Inherits:
Object show all
Defined in:
lib/fcgi_handler.rb

Constant Summary collapse

SIGNALS =
{
  'HUP'     => :reload,
  'TERM'    => :exit_now,
  'USR1'    => :exit,
  'USR2'    => :restart,
  'SIGTRAP' => :breakpoint
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(log_file_path = nil, gc_request_period = nil) {|_self| ... } ⇒ RailsFCGIHandler

Initialize the FastCGI instance with the path to a crash log detailing unhandled exceptions (default RAILS_ROOT/log/fastcgi.crash.log) and the number of requests to process between garbage collection runs (default nil for normal GC behavior.) Optionally, pass a block which takes this instance as an argument for further configuration.

Yields:

  • (_self)

Yield Parameters:



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/fcgi_handler.rb', line 31

def initialize(log_file_path = nil, gc_request_period = nil)
  self.log_file_path = log_file_path || "#{RAILS_ROOT}/log/fastcgi.crash.log"
  self.gc_request_period = gc_request_period

  # Yield for additional configuration.
  yield self if block_given?

  # Safely install signal handlers.
  install_signal_handlers

  # Start error timestamp at 11 seconds ago.
  @last_error_on = Time.now - 11

  dispatcher_log :info, "starting"
end

Instance Attribute Details

#gc_request_periodObject

Returns the value of attribute gc_request_period.



18
19
20
# File 'lib/fcgi_handler.rb', line 18

def gc_request_period
  @gc_request_period
end

#log_file_pathObject

Returns the value of attribute log_file_path.



17
18
19
# File 'lib/fcgi_handler.rb', line 17

def log_file_path
  @log_file_path
end

#when_readyObject (readonly)

Returns the value of attribute when_ready.



15
16
17
# File 'lib/fcgi_handler.rb', line 15

def when_ready
  @when_ready
end

Class Method Details

.process!(*args, &block) ⇒ Object

Initialize and run the FastCGI instance, passing arguments through to new.



22
23
24
# File 'lib/fcgi_handler.rb', line 22

def self.process!(*args, &block)
  new(*args, &block).process!
end

Instance Method Details

#process!(provider = FCGI) ⇒ Object



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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/fcgi_handler.rb', line 47

def process!(provider = FCGI)
  # Make a note of $" so we can safely reload this instance.
  mark!

  run_gc! if gc_request_period

  provider.each_cgi do |cgi| 
    process_request(cgi)

    case when_ready
      when :reload
        reload!
      when :restart
        close_connection(cgi)
        restart!
      when :exit
        close_connection(cgi)
        break
      when :breakpoint
        close_connection(cgi)
        breakpoint!
    end

    gc_countdown
  end

  GC.enable
  dispatcher_log :info, "terminated gracefully"

rescue SystemExit => exit_error
  dispatcher_log :info, "terminated by explicit exit"

rescue Object => fcgi_error
  # retry on errors that would otherwise have terminated the FCGI process,
  # but only if they occur more than 10 seconds apart.
  if !(SignalException === fcgi_error) && Time.now - @last_error_on > 10
    @last_error_on = Time.now
    dispatcher_error(fcgi_error, "almost killed by this error")
    retry
  else
    dispatcher_error(fcgi_error, "killed by this error")
  end
end