unicorn 2.x updates + kgio
[rainbows.git] / lib / rainbows / http_server.rb
blob0ed6717a2a6901e923f73b505e893aec1ee67f6e
1 # -*- encoding: binary -*-
2 # :enddoc:
3 module Rainbows
5   class HttpServer < ::Unicorn::HttpServer
6     include Rainbows
8     class << self
9       def setup(block)
10         G.server.instance_eval(&block)
11       end
12     end
14     def initialize(app, options)
15       G.server = self
16       @logger = Unicorn::Configurator::DEFAULTS[:logger]
17       rv = super(app, options)
18       defined?(@use) or use(:Base)
19       @worker_connections ||= MODEL_WORKER_CONNECTIONS[@use]
20     end
22     def reopen_worker_logs(worker_nr)
23       logger.info "worker=#{worker_nr} reopening logs..."
24       Unicorn::Util.reopen_logs
25       logger.info "worker=#{worker_nr} done reopening logs"
26       rescue
27         G.quit! # let the master reopen and refork us
28     end
30     #:stopdoc:
31     #
32     # Add one second to the timeout since our fchmod heartbeat is less
33     # precise (and must be more conservative) than Unicorn does.  We
34     # handle many clients per process and can't chmod on every
35     # connection we accept without wasting cycles.  That added to the
36     # fact that we let clients keep idle connections open for long
37     # periods of time means we have to chmod at a fixed interval.
38     def timeout=(nr)
39       @timeout = nr + 1
40     end
41     #:startdoc:
43     def use(*args)
44       model = args.shift or return @use
45       mod = begin
46         Rainbows.const_get(model)
47       rescue NameError => e
48         logger.error "error loading #{model.inspect}: #{e}"
49         e.backtrace.each { |l| logger.error l }
50         raise ArgumentError, "concurrency model #{model.inspect} not supported"
51       end
53       Module === mod or
54         raise ArgumentError, "concurrency model #{model.inspect} not supported"
55       extend(mod)
56       args.each do |opt|
57         case opt
58         when Hash; O.update(opt)
59         when Symbol; O[opt] = true
60         else; raise ArgumentError, "can't handle option: #{opt.inspect}"
61         end
62       end
63       mod.setup if mod.respond_to?(:setup)
64       Const::RACK_DEFAULTS['rainbows.model'] = @use = model.to_sym
65       Const::RACK_DEFAULTS['rack.multithread'] = !!(model.to_s =~ /Thread/)
67       case @use
68       when :Rev, :EventMachine, :NeverBlock
69         Const::RACK_DEFAULTS['rainbows.autochunk'] = true
70       end
71     end
73     def worker_connections(*args)
74       return @worker_connections if args.empty?
75       nr = args[0]
76       (Integer === nr && nr > 0) or
77         raise ArgumentError, "worker_connections must be a positive Integer"
78       @worker_connections = nr
79     end
81     def keepalive_timeout(nr)
82       (Integer === nr && nr >= 0) or
83         raise ArgumentError, "keepalive must be a non-negative Integer"
84       G.kato = nr
85     end
87     def client_max_body_size(nr)
88       err = "client_max_body_size must be nil or a non-negative Integer"
89       case nr
90       when nil
91       when Integer
92         nr >= 0 or raise ArgumentError, err
93       else
94         raise ArgumentError, err
95       end
96       Rainbows.max_bytes = nr
97     end
98   end