mongrel 0.3.11 → 0.3.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +4 -2
- data/bin/mongrel_rails +65 -101
- data/bin/mongrel_rails_service +1 -1
- data/bin/mongrel_rails_svc +131 -115
- data/doc/rdoc/classes/Class.html +197 -0
- data/doc/rdoc/classes/Class.src/M000001.html +24 -0
- data/doc/rdoc/classes/Class.src/M000002.html +62 -0
- data/doc/rdoc/classes/Class.src/M000003.html +21 -0
- data/doc/rdoc/classes/Class.src/M000004.html +20 -0
- data/doc/rdoc/classes/IO.html +170 -0
- data/doc/rdoc/classes/IO.src/M000005.html +19 -0
- data/doc/rdoc/classes/IO.src/M000006.html +19 -0
- data/doc/rdoc/classes/Kernel.html +159 -0
- data/doc/rdoc/classes/Kernel.src/M000025.html +19 -0
- data/doc/rdoc/classes/Kernel.src/M000026.html +25 -0
- data/doc/rdoc/classes/Mongrel.html +181 -0
- data/doc/rdoc/classes/Mongrel/CGIWrapper.html +383 -0
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000090.html +24 -0
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000091.html +47 -0
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000092.html +34 -0
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000093.html +27 -0
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000094.html +25 -0
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000095.html +18 -0
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000096.html +18 -0
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000097.html +18 -0
- data/doc/rdoc/classes/Mongrel/CGIWrapper.src/M000098.html +19 -0
- data/doc/rdoc/classes/Mongrel/Camping.html +177 -0
- data/doc/rdoc/classes/Mongrel/Camping.src/M000048.html +22 -0
- data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.html +165 -0
- data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.src/M000049.html +18 -0
- data/doc/rdoc/classes/Mongrel/Camping/CampingHandler.src/M000050.html +27 -0
- data/doc/rdoc/classes/Mongrel/Command.html +119 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.html +337 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000029.html +24 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000030.html +41 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000031.html +18 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000032.html +18 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000033.html +18 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000034.html +22 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000035.html +18 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000036.html +18 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000037.html +18 -0
- data/doc/rdoc/classes/Mongrel/Command/Base.src/M000038.html +18 -0
- data/doc/rdoc/classes/Mongrel/Command/Registry.html +192 -0
- data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000039.html +20 -0
- data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000040.html +25 -0
- data/doc/rdoc/classes/Mongrel/Command/Registry.src/M000041.html +46 -0
- data/doc/rdoc/classes/Mongrel/Configurator.html +563 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000099.html +24 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000100.html +23 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000101.html +18 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000102.html +32 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000103.html +19 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000104.html +31 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000105.html +33 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000106.html +18 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000107.html +25 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000108.html +19 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000109.html +22 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000110.html +21 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000111.html +18 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000112.html +27 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000113.html +46 -0
- data/doc/rdoc/classes/Mongrel/Configurator.src/M000114.html +18 -0
- data/doc/rdoc/classes/Mongrel/Const.html +286 -0
- data/doc/rdoc/classes/Mongrel/DirHandler.html +288 -0
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000058.html +20 -0
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000059.html +42 -0
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000060.html +40 -0
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000061.html +51 -0
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000062.html +40 -0
- data/doc/rdoc/classes/Mongrel/DirHandler.src/M000063.html +18 -0
- data/doc/rdoc/classes/Mongrel/Error404Handler.html +171 -0
- data/doc/rdoc/classes/Mongrel/Error404Handler.src/M000115.html +18 -0
- data/doc/rdoc/classes/Mongrel/Error404Handler.src/M000116.html +18 -0
- data/doc/rdoc/classes/Mongrel/HeaderOut.html +185 -0
- data/doc/rdoc/classes/Mongrel/HeaderOut.src/M000072.html +18 -0
- data/doc/rdoc/classes/Mongrel/HeaderOut.src/M000073.html +18 -0
- data/doc/rdoc/classes/Mongrel/HttpHandler.html +152 -0
- data/doc/rdoc/classes/Mongrel/HttpHandler.src/M000074.html +17 -0
- data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.html +169 -0
- data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000027.html +18 -0
- data/doc/rdoc/classes/Mongrel/HttpHandlerPlugin.src/M000028.html +17 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.html +271 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000051.html +28 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000052.html +29 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000053.html +29 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000054.html +41 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000055.html +27 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000056.html +27 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/M000057.html +28 -0
- data/doc/rdoc/classes/Mongrel/HttpRequest.html +222 -0
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000117.html +28 -0
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000118.html +20 -0
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000119.html +20 -0
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/M000120.html +32 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.html +371 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000075.html +26 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000076.html +20 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000077.html +25 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000078.html +22 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000079.html +22 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000080.html +23 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000081.html +18 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000082.html +20 -0
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/M000083.html +18 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.html +360 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000064.html +24 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000065.html +65 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000066.html +24 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000067.html +60 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000068.html +28 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000069.html +18 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000070.html +22 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000071.html +18 -0
- data/doc/rdoc/classes/Mongrel/Rails.html +112 -0
- data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.html +223 -0
- data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000042.html +35 -0
- data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000043.html +25 -0
- data/doc/rdoc/classes/Mongrel/Rails/RailsConfigurator.src/M000044.html +32 -0
- data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.html +250 -0
- data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000045.html +22 -0
- data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000046.html +48 -0
- data/doc/rdoc/classes/Mongrel/Rails/RailsHandler.src/M000047.html +23 -0
- data/doc/rdoc/classes/Mongrel/StopServer.html +117 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.html +301 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000084.html +18 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000085.html +18 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000086.html +39 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000087.html +51 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000088.html +36 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000089.html +83 -0
- data/doc/rdoc/classes/MongrelDbg.html +209 -0
- data/doc/rdoc/classes/MongrelDbg.src/M000020.html +19 -0
- data/doc/rdoc/classes/MongrelDbg.src/M000021.html +20 -0
- data/doc/rdoc/classes/MongrelDbg.src/M000022.html +22 -0
- data/doc/rdoc/classes/MongrelDbg.src/M000023.html +21 -0
- data/doc/rdoc/classes/MongrelDbg.src/M000024.html +18 -0
- data/doc/rdoc/classes/ObjectTracker.html +176 -0
- data/doc/rdoc/classes/ObjectTracker.src/M000016.html +22 -0
- data/doc/rdoc/classes/ObjectTracker.src/M000017.html +18 -0
- data/doc/rdoc/classes/ObjectTracker.src/M000018.html +18 -0
- data/doc/rdoc/classes/ObjectTracker.src/M000019.html +46 -0
- data/doc/rdoc/classes/RequestLog.html +113 -0
- data/doc/rdoc/classes/RequestLog/Files.html +144 -0
- data/doc/rdoc/classes/RequestLog/Files.src/M000121.html +19 -0
- data/doc/rdoc/classes/RequestLog/Objects.html +144 -0
- data/doc/rdoc/classes/RequestLog/Objects.src/M000122.html +19 -0
- data/doc/rdoc/classes/RequestLog/Params.html +144 -0
- data/doc/rdoc/classes/RequestLog/Params.src/M000123.html +19 -0
- data/doc/rdoc/classes/Stats.html +306 -0
- data/doc/rdoc/classes/Stats.src/M000009.html +19 -0
- data/doc/rdoc/classes/Stats.src/M000010.html +23 -0
- data/doc/rdoc/classes/Stats.src/M000011.html +26 -0
- data/doc/rdoc/classes/Stats.src/M000012.html +18 -0
- data/doc/rdoc/classes/Stats.src/M000013.html +18 -0
- data/doc/rdoc/classes/Stats.src/M000014.html +19 -0
- data/doc/rdoc/classes/Stats.src/M000015.html +20 -0
- data/doc/rdoc/classes/TCPServer.html +173 -0
- data/doc/rdoc/classes/TCPServer.src/M000007.html +19 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/COPYING.html +756 -0
- data/doc/rdoc/files/LICENSE.html +756 -0
- data/doc/rdoc/files/README.html +302 -0
- data/doc/rdoc/files/ext/http11/http11_c.html +101 -0
- data/doc/rdoc/files/lib/mongrel/camping_rb.html +108 -0
- data/doc/rdoc/files/lib/mongrel/cgi_rb.html +108 -0
- data/doc/rdoc/files/lib/mongrel/command_rb.html +111 -0
- data/doc/rdoc/files/lib/mongrel/debug_rb.html +110 -0
- data/doc/rdoc/files/lib/mongrel/handlers_rb.html +109 -0
- data/doc/rdoc/files/lib/mongrel/init_rb.html +109 -0
- data/doc/rdoc/files/lib/mongrel/rails_rb.html +111 -0
- data/doc/rdoc/files/lib/mongrel/stats_rb.html +117 -0
- data/doc/rdoc/files/lib/mongrel/tcphack_rb.html +109 -0
- data/doc/rdoc/files/lib/mongrel_rb.html +118 -0
- data/doc/rdoc/fr_class_index.html +60 -0
- data/doc/rdoc/fr_file_index.html +40 -0
- data/doc/rdoc/fr_method_index.html +149 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/examples/builder.rb +29 -0
- data/examples/camping/blog.rb +11 -2
- data/examples/simpletest.rb +20 -7
- data/ext/http11/http11.c +71 -14
- data/ext/http11/http11_parser.c +27 -24
- data/ext/http11/http11_parser.h +2 -1
- data/lib/http11.bundle +0 -0
- data/lib/mongrel.rb +498 -135
- data/lib/mongrel/command.rb +1 -1
- data/lib/mongrel/debug.rb +259 -0
- data/lib/mongrel/handlers.rb +76 -22
- data/lib/mongrel/rails.rb +165 -72
- data/lib/mongrel/stats.rb +71 -0
- data/test/test_configurator.rb +67 -0
- data/test/test_debug.rb +31 -0
- data/test/test_http11.rb +16 -0
- data/test/test_response.rb +5 -0
- data/test/test_stats.rb +28 -0
- metadata +224 -2
data/lib/mongrel/command.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Mongrel
|
|
|
15
15
|
# user's bidding.
|
|
16
16
|
module Base
|
|
17
17
|
|
|
18
|
-
attr_reader :valid, :done_validating
|
|
18
|
+
attr_reader :valid, :done_validating, :original_args
|
|
19
19
|
|
|
20
20
|
# Called by the implemented command to set the options for that command.
|
|
21
21
|
# Every option has a short and long version, a description, a variable to
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
require 'set'
|
|
3
|
+
require 'socket'
|
|
4
|
+
|
|
5
|
+
$mongrel_debugging=true
|
|
6
|
+
|
|
7
|
+
module MongrelDbg
|
|
8
|
+
SETTINGS = { :tracing => {}}
|
|
9
|
+
LOGGING = { }
|
|
10
|
+
|
|
11
|
+
def MongrelDbg::configure(log_dir = "log/mongrel_debug")
|
|
12
|
+
Dir.mkdir(log_dir) if not File.exist?(log_dir)
|
|
13
|
+
@log_dir = log_dir
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def MongrelDbg::trace(target, message)
|
|
18
|
+
if SETTINGS[:tracing][target] and LOGGING[target]
|
|
19
|
+
LOGGING[target].log(Logger::DEBUG, message)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def MongrelDbg::begin_trace(target)
|
|
24
|
+
SETTINGS[:tracing][target] = true
|
|
25
|
+
if not LOGGING[target]
|
|
26
|
+
LOGGING[target] = Logger.new(File.join(@log_dir, "#{target.to_s}.log"))
|
|
27
|
+
end
|
|
28
|
+
MongrelDbg::trace(target, "TRACING ON #{Time.now}")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def MongrelDbg::end_trace(target)
|
|
32
|
+
SETTINGS[:tracing][target] = false
|
|
33
|
+
MongrelDbg::trace(target, "TRACING OFF #{Time.now}")
|
|
34
|
+
LOGGING[target].close
|
|
35
|
+
LOGGING[target] = nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def MongrelDbg::tracing?(target)
|
|
39
|
+
SETTINGS[:tracing][target]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
module ObjectTracker
|
|
45
|
+
@active_objects = nil
|
|
46
|
+
@live_object_tracking = true
|
|
47
|
+
|
|
48
|
+
def ObjectTracker.configure
|
|
49
|
+
@active_objects = Set.new
|
|
50
|
+
|
|
51
|
+
ObjectSpace.each_object do |obj|
|
|
52
|
+
@active_objects << obj.object_id
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def ObjectTracker.start
|
|
58
|
+
@live_object_tracking = true
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def ObjectTracker.stop
|
|
62
|
+
@live_object_tracking = false
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def ObjectTracker.sample
|
|
66
|
+
Class.stopit do
|
|
67
|
+
ospace = Set.new
|
|
68
|
+
counts = {}
|
|
69
|
+
|
|
70
|
+
# Strings can't be tracked easily and are so numerous that they drown out all else
|
|
71
|
+
# so we just ignore them in the counts.
|
|
72
|
+
ObjectSpace.each_object do |obj|
|
|
73
|
+
if not obj.kind_of? String
|
|
74
|
+
ospace << obj.object_id
|
|
75
|
+
counts[obj.class] ||= 0
|
|
76
|
+
counts[obj.class] += 1
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
dead_objects = @active_objects - ospace
|
|
81
|
+
new_objects = ospace - @active_objects
|
|
82
|
+
live_objects = ospace & @active_objects
|
|
83
|
+
|
|
84
|
+
MongrelDbg::trace(:objects, "COUNTS: #{dead_objects.length},#{new_objects.length},#{live_objects.length}")
|
|
85
|
+
|
|
86
|
+
if MongrelDbg::tracing? :objects
|
|
87
|
+
top_20 = counts.sort{|a,b| b[1] <=> a[1]}[0..20]
|
|
88
|
+
MongrelDbg::trace(:objects,"TOP 20: #{top_20.inspect}")
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
@active_objects = live_objects + new_objects
|
|
92
|
+
|
|
93
|
+
[@active_objects, top_20]
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
$open_files = {}
|
|
100
|
+
|
|
101
|
+
class IO
|
|
102
|
+
alias_method :orig_open, :open
|
|
103
|
+
alias_method :orig_close, :close
|
|
104
|
+
|
|
105
|
+
def open(*arg, &blk)
|
|
106
|
+
$open_files[self] = args.inspect
|
|
107
|
+
orig_open(*arg,&blk)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def close(*arg,&blk)
|
|
111
|
+
$open_files.delete self
|
|
112
|
+
orig_close(*arg,&blk)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
module Kernel
|
|
118
|
+
alias_method :orig_open, :open
|
|
119
|
+
|
|
120
|
+
def open(*arg, &blk)
|
|
121
|
+
$open_files[self] = arg[0]
|
|
122
|
+
orig_open(*arg,&blk)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def log_open_files
|
|
126
|
+
Class.stopit do
|
|
127
|
+
open_counts = {}
|
|
128
|
+
$open_files.each do |f,args|
|
|
129
|
+
open_counts[args] ||= 0
|
|
130
|
+
open_counts[args] += 1
|
|
131
|
+
end
|
|
132
|
+
MongrelDbg::trace(:files, open_counts.to_yaml)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class Class
|
|
140
|
+
alias_method :orig_new, :new
|
|
141
|
+
|
|
142
|
+
@@count = 0
|
|
143
|
+
@@stopit = false
|
|
144
|
+
@@class_caller_count = Hash.new{|hash,key| hash[key] = Hash.new(0)}
|
|
145
|
+
|
|
146
|
+
def new(*arg,&blk)
|
|
147
|
+
unless @@stopit
|
|
148
|
+
@@stopit = true
|
|
149
|
+
@@count += 1
|
|
150
|
+
@@class_caller_count[self][caller.join("\n\t")] += 1
|
|
151
|
+
@@stopit = false
|
|
152
|
+
end
|
|
153
|
+
orig_new(*arg,&blk)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def Class.report_object_creations(out=$stderr, more_than=20)
|
|
158
|
+
Class.stopit do
|
|
159
|
+
out.puts "Number of objects created = #{@@count}"
|
|
160
|
+
|
|
161
|
+
total = Hash.new(0)
|
|
162
|
+
|
|
163
|
+
@@class_caller_count.each_key do |klass|
|
|
164
|
+
caller_count = @@class_caller_count[klass]
|
|
165
|
+
caller_count.each_value do |count|
|
|
166
|
+
total[klass] += count
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
klass_list = total.keys.sort{|klass_a, klass_b|
|
|
171
|
+
a = total[klass_a]
|
|
172
|
+
b = total[klass_b]
|
|
173
|
+
if a != b
|
|
174
|
+
-1* (a <=> b)
|
|
175
|
+
else
|
|
176
|
+
klass_a.to_s <=> klass_b.to_s
|
|
177
|
+
end
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
below_count = 0
|
|
181
|
+
|
|
182
|
+
klass_list.each do |klass|
|
|
183
|
+
below_calls = 0
|
|
184
|
+
if total[klass] > more_than
|
|
185
|
+
out.puts "#{total[klass]}\t#{klass} objects created."
|
|
186
|
+
caller_count = @@class_caller_count[ klass]
|
|
187
|
+
caller_count.keys.sort_by{|call| -1*caller_count[call]}.each do |call|
|
|
188
|
+
if caller_count[call] > more_than
|
|
189
|
+
out.puts "\t** #{caller_count[call]} #{klass} objects AT:"
|
|
190
|
+
out.puts "\t#{call}\n\n"
|
|
191
|
+
else
|
|
192
|
+
below_calls += 1
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
out.puts "\t#{below_calls} more objects had calls less that #{more_than} limit.\n\n" if below_calls > 0
|
|
196
|
+
else
|
|
197
|
+
below_count += 1
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
out.puts "\t** #{below_count} More objects were created but the count was below the #{more_than} limit." if below_count > 0
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def Class.reset_object_creations
|
|
206
|
+
Class.stopit do
|
|
207
|
+
@@count = 0
|
|
208
|
+
@@class_caller_count = Hash.new{|hash,key| hash[key] = Hash.new(0)}
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def Class.stopit
|
|
213
|
+
@@stopit = true
|
|
214
|
+
yield
|
|
215
|
+
@@stopit = false
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
module RequestLog
|
|
222
|
+
class Files < GemPlugin::Plugin "/handlers"
|
|
223
|
+
include Mongrel::HttpHandlerPlugin
|
|
224
|
+
|
|
225
|
+
def process(request, response)
|
|
226
|
+
MongrelDbg::trace(:files, "#{Time.now} FILES OPEN BEFORE REQUEST #{request.params['PATH_INFO']}")
|
|
227
|
+
log_open_files
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
class Objects < GemPlugin::Plugin "/handlers"
|
|
233
|
+
include Mongrel::HttpHandlerPlugin
|
|
234
|
+
|
|
235
|
+
def process(request, response)
|
|
236
|
+
MongrelDbg::trace(:objects, "#{Time.now} OBJECT STATS BEFORE REQUEST #{request.params['PATH_INFO']}")
|
|
237
|
+
ObjectTracker.sample
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class Params < GemPlugin::Plugin "/handlers"
|
|
244
|
+
include Mongrel::HttpHandlerPlugin
|
|
245
|
+
|
|
246
|
+
def process(request, response)
|
|
247
|
+
MongrelDbg::trace(:rails, "#{Time.now} REQUEST #{request.params['PATH_INFO']}")
|
|
248
|
+
MongrelDbg::trace(:rails, request.params.to_yaml)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
END {
|
|
256
|
+
open("log/mongrel_debug/object_tracking.log", "w") {|f| Class.report_object_creations(f) }
|
|
257
|
+
MongrelDbg::trace(:files, "FILES OPEN AT EXIT")
|
|
258
|
+
log_open_files
|
|
259
|
+
}
|
data/lib/mongrel/handlers.rb
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
begin
|
|
3
|
+
require 'sendfile'
|
|
4
|
+
$mongrel_has_sendfile = true
|
|
5
|
+
STDERR.puts "** You have sendfile installed, will use that to serve files."
|
|
6
|
+
rescue Object
|
|
7
|
+
$mongrel_has_sendfile = false
|
|
8
|
+
end
|
|
1
9
|
|
|
2
10
|
module Mongrel
|
|
3
11
|
|
|
@@ -5,12 +13,35 @@ module Mongrel
|
|
|
5
13
|
# just the minimum necessary for you to handle a request and shoot back
|
|
6
14
|
# a response. Look at the HttpRequest and HttpResponse objects for how
|
|
7
15
|
# to use them.
|
|
16
|
+
#
|
|
17
|
+
# This is used for very simple handlers that don't require much to operate.
|
|
18
|
+
# More extensive plugins or those you intend to distribute as GemPlugins
|
|
19
|
+
# should be implemented using the HttpHandlerPlugin mixin.
|
|
20
|
+
#
|
|
8
21
|
class HttpHandler
|
|
22
|
+
|
|
9
23
|
def process(request, response)
|
|
10
24
|
end
|
|
11
25
|
end
|
|
12
26
|
|
|
13
27
|
|
|
28
|
+
# This is used when your handler is implemented as a GemPlugin.
|
|
29
|
+
# The plugin always takes an options hash which you can modify
|
|
30
|
+
# and then access later. They are stored by default for
|
|
31
|
+
# the process method later.
|
|
32
|
+
module HttpHandlerPlugin
|
|
33
|
+
attr_reader :options
|
|
34
|
+
|
|
35
|
+
def initialize(options={})
|
|
36
|
+
@options = options
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def process(request, response)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
14
45
|
# The server normally returns a 404 response if an unknown URI is requested, but it
|
|
15
46
|
# also returns a lame empty message. This lets you do a 404 response
|
|
16
47
|
# with a custom message for special URIs.
|
|
@@ -53,6 +84,7 @@ module Mongrel
|
|
|
53
84
|
".txt" => "text/plain"
|
|
54
85
|
}
|
|
55
86
|
|
|
87
|
+
ONLY_HEAD_GET="Only HEAD and GET allowed.".freeze
|
|
56
88
|
|
|
57
89
|
attr_reader :path
|
|
58
90
|
|
|
@@ -103,7 +135,7 @@ module Mongrel
|
|
|
103
135
|
|
|
104
136
|
if @listing_allowed
|
|
105
137
|
response.start(200) do |head,out|
|
|
106
|
-
head[
|
|
138
|
+
head[Const::CONTENT_TYPE] = "text/html"
|
|
107
139
|
out << "<html><head><title>Directory Listing</title></head><body>"
|
|
108
140
|
Dir.entries(dir).each do |child|
|
|
109
141
|
next if child == "."
|
|
@@ -126,20 +158,40 @@ module Mongrel
|
|
|
126
158
|
|
|
127
159
|
# Sends the contents of a file back to the user. Not terribly efficient since it's
|
|
128
160
|
# opening and closing the file for each read.
|
|
129
|
-
def send_file(req, response)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
161
|
+
def send_file(req, response, header_only=false)
|
|
162
|
+
|
|
163
|
+
# first we setup the headers and status then we do a very fast send on the socket directly
|
|
164
|
+
response.status = 200
|
|
165
|
+
|
|
166
|
+
# set the mime type from our map based on the ending
|
|
167
|
+
dot_at = req.rindex(".")
|
|
168
|
+
if dot_at
|
|
169
|
+
ext = req[dot_at .. -1]
|
|
170
|
+
if MIME_TYPES[ext]
|
|
171
|
+
stat = File.stat(req)
|
|
172
|
+
response.header[Const::CONTENT_TYPE] = MIME_TYPES[ext]
|
|
173
|
+
# TODO: Confirm this works for rfc 1123
|
|
174
|
+
response.header[Const::LAST_MODIFIED] = HttpServer.httpdate(stat.mtime)
|
|
175
|
+
# TODO that this is a valid way to calculate an etag
|
|
176
|
+
response.header[Const::ETAG] = Const::ETAG_FORMAT % [stat.mtime.to_i, stat.size, stat.ino]
|
|
138
177
|
end
|
|
178
|
+
end
|
|
139
179
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
180
|
+
response.send_status(File.size(req))
|
|
181
|
+
response.send_header
|
|
182
|
+
|
|
183
|
+
if not header_only
|
|
184
|
+
begin
|
|
185
|
+
if $mongrel_has_sendfile
|
|
186
|
+
File.open(req, "rb") { |f| response.socket.sendfile(f) }
|
|
187
|
+
else
|
|
188
|
+
File.open(req, "rb") { |f| response.socket.write(f.read) }
|
|
189
|
+
end
|
|
190
|
+
rescue EOFError,Errno::ECONNRESET,Errno::EPIPE
|
|
191
|
+
# ignore these since it means the client closed off early
|
|
192
|
+
end
|
|
193
|
+
else
|
|
194
|
+
response.send_body # should send nothing
|
|
143
195
|
end
|
|
144
196
|
end
|
|
145
197
|
|
|
@@ -147,7 +199,8 @@ module Mongrel
|
|
|
147
199
|
# Process the request to either serve a file or a directory listing
|
|
148
200
|
# if allowed (based on the listing_allowed paramter to the constructor).
|
|
149
201
|
def process(request, response)
|
|
150
|
-
|
|
202
|
+
req_method = request.params[Const::REQUEST_METHOD] || Const::GET
|
|
203
|
+
req = can_serve request.params[Const::PATH_INFO]
|
|
151
204
|
if not req
|
|
152
205
|
# not found, return a 404
|
|
153
206
|
response.start(404) do |head,out|
|
|
@@ -156,16 +209,17 @@ module Mongrel
|
|
|
156
209
|
else
|
|
157
210
|
begin
|
|
158
211
|
if File.directory? req
|
|
159
|
-
send_dir_listing(request.params[
|
|
160
|
-
|
|
161
|
-
send_file(req, response)
|
|
212
|
+
send_dir_listing(request.params[Const::REQUEST_URI],req, response)
|
|
213
|
+
elsif req_method == Const::HEAD
|
|
214
|
+
send_file(req, response, true)
|
|
215
|
+
elsif req_method == Const::GET
|
|
216
|
+
send_file(req, response, false)
|
|
217
|
+
else
|
|
218
|
+
response.start(403) {|head,out| out.write(ONLY_HEAD_GET) }
|
|
162
219
|
end
|
|
163
220
|
rescue => details
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
out << "Error accessing file: #{details}"
|
|
167
|
-
out << details.backtrace.join("\n")
|
|
168
|
-
end
|
|
221
|
+
STDERR.puts "Error accessing file #{req}: #{details}"
|
|
222
|
+
STDERR.puts details.backtrace.join("\n")
|
|
169
223
|
end
|
|
170
224
|
end
|
|
171
225
|
end
|
data/lib/mongrel/rails.rb
CHANGED
|
@@ -1,85 +1,178 @@
|
|
|
1
1
|
require 'mongrel'
|
|
2
2
|
require 'cgi'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# application with Mongrel during development and testing, then use it
|
|
7
|
-
# also in production behind a server that's better at serving the
|
|
8
|
-
# static files.
|
|
9
|
-
#
|
|
10
|
-
# The RailsHandler takes a mime_map parameter which is a simple suffix=mimetype
|
|
11
|
-
# mapping that it should add to the list of valid mime types.
|
|
12
|
-
#
|
|
13
|
-
# It also supports page caching directly and will try to resolve a request
|
|
14
|
-
# in the following order:
|
|
15
|
-
#
|
|
16
|
-
# * If the requested exact PATH_INFO exists as a file then serve it.
|
|
17
|
-
# * If it exists at PATH_INFO+".html" exists then serve that.
|
|
18
|
-
# * Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispath to have Rails go.
|
|
19
|
-
#
|
|
20
|
-
# This means that if you are using page caching it will actually work with Mongrel
|
|
21
|
-
# and you should see a decent speed boost (but not as fast as if you use lighttpd).
|
|
22
|
-
#
|
|
23
|
-
# An additional feature you can use is
|
|
24
|
-
class RailsHandler < Mongrel::HttpHandler
|
|
25
|
-
attr_reader :files
|
|
26
|
-
attr_reader :guard
|
|
27
|
-
|
|
28
|
-
def initialize(dir, mime_map = {})
|
|
29
|
-
@files = Mongrel::DirHandler.new(dir,false)
|
|
30
|
-
@guard = Mutex.new
|
|
4
|
+
module Mongrel
|
|
5
|
+
module Rails
|
|
31
6
|
|
|
32
|
-
# register the requested mime types
|
|
33
|
-
mime_map.each {|k,v| Mongrel::DirHandler::add_mime_type(k,v) }
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Attempts to resolve the request as follows:
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
# * If the requested exact PATH_INFO exists as a file then serve it.
|
|
40
|
-
# * If it exists at PATH_INFO+".html" exists then serve that.
|
|
41
|
-
# * Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispath to have Rails go.
|
|
42
|
-
def process(request, response)
|
|
43
|
-
return if response.socket.closed?
|
|
44
|
-
|
|
45
|
-
path_info = request.params[Mongrel::Const::PATH_INFO]
|
|
46
|
-
page_cached = request.params[Mongrel::Const::PATH_INFO] + ".html"
|
|
47
|
-
|
|
48
|
-
if @files.can_serve(path_info)
|
|
49
|
-
# File exists as-is so serve it up
|
|
50
|
-
@files.process(request,response)
|
|
51
|
-
elsif @files.can_serve(page_cached)
|
|
52
|
-
# possible cached page, serve it up
|
|
53
|
-
request.params[Mongrel::Const::PATH_INFO] = page_cached
|
|
54
|
-
@files.process(request,response)
|
|
55
|
-
else
|
|
56
|
-
begin
|
|
57
|
-
cgi = Mongrel::CGIWrapper.new(request, response)
|
|
58
|
-
cgi.handler = self
|
|
59
7
|
|
|
8
|
+
# Implements a handler that can run Rails and serve files out of the
|
|
9
|
+
# Rails application's public directory. This lets you run your Rails
|
|
10
|
+
# application with Mongrel during development and testing, then use it
|
|
11
|
+
# also in production behind a server that's better at serving the
|
|
12
|
+
# static files.
|
|
13
|
+
#
|
|
14
|
+
# The RailsHandler takes a mime_map parameter which is a simple suffix=mimetype
|
|
15
|
+
# mapping that it should add to the list of valid mime types.
|
|
16
|
+
#
|
|
17
|
+
# It also supports page caching directly and will try to resolve a request
|
|
18
|
+
# in the following order:
|
|
19
|
+
#
|
|
20
|
+
# * If the requested exact PATH_INFO exists as a file then serve it.
|
|
21
|
+
# * If it exists at PATH_INFO+".html" exists then serve that.
|
|
22
|
+
# * Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispath to have Rails go.
|
|
23
|
+
#
|
|
24
|
+
# This means that if you are using page caching it will actually work with Mongrel
|
|
25
|
+
# and you should see a decent speed boost (but not as fast as if you use lighttpd).
|
|
26
|
+
#
|
|
27
|
+
# An additional feature you can use is
|
|
28
|
+
class RailsHandler < Mongrel::HttpHandler
|
|
29
|
+
attr_reader :files
|
|
30
|
+
attr_reader :guard
|
|
31
|
+
|
|
32
|
+
def initialize(dir, mime_map = {})
|
|
33
|
+
@files = Mongrel::DirHandler.new(dir,false)
|
|
34
|
+
@guard = Mutex.new
|
|
35
|
+
|
|
36
|
+
# register the requested mime types
|
|
37
|
+
mime_map.each {|k,v| Mongrel::DirHandler::add_mime_type(k,v) }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Attempts to resolve the request as follows:
|
|
41
|
+
#
|
|
42
|
+
#
|
|
43
|
+
# * If the requested exact PATH_INFO exists as a file then serve it.
|
|
44
|
+
# * If it exists at PATH_INFO+".html" exists then serve that.
|
|
45
|
+
# * Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispath to have Rails go.
|
|
46
|
+
def process(request, response)
|
|
47
|
+
return if response.socket.closed?
|
|
48
|
+
|
|
49
|
+
path_info = request.params[Mongrel::Const::PATH_INFO]
|
|
50
|
+
page_cached = request.params[Mongrel::Const::PATH_INFO] + ".html"
|
|
51
|
+
|
|
52
|
+
if @files.can_serve(path_info)
|
|
53
|
+
# File exists as-is so serve it up
|
|
54
|
+
@files.process(request,response)
|
|
55
|
+
elsif @files.can_serve(page_cached)
|
|
56
|
+
# possible cached page, serve it up
|
|
57
|
+
request.params[Mongrel::Const::PATH_INFO] = page_cached
|
|
58
|
+
@files.process(request,response)
|
|
59
|
+
else
|
|
60
|
+
begin
|
|
61
|
+
cgi = Mongrel::CGIWrapper.new(request, response)
|
|
62
|
+
cgi.handler = self
|
|
63
|
+
|
|
64
|
+
@guard.synchronize do
|
|
65
|
+
# Rails is not thread safe so must be run entirely within synchronize
|
|
66
|
+
Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# This finalizes the output using the proper HttpResponse way
|
|
70
|
+
cgi.out {""}
|
|
71
|
+
rescue Errno::EPIPE
|
|
72
|
+
# ignored
|
|
73
|
+
rescue Object => rails_error
|
|
74
|
+
STDERR.puts "Error calling Dispatcher.dispatch #{rails_error.inspect}"
|
|
75
|
+
STDERR.puts rails_error.backtrace.join("\n")
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# Does the internal reload for Rails. It might work for most cases, but
|
|
82
|
+
# sometimes you get exceptions. In that case just do a real restart.
|
|
83
|
+
def reload!
|
|
60
84
|
@guard.synchronize do
|
|
61
|
-
|
|
62
|
-
|
|
85
|
+
$".replace $orig_dollar_quote
|
|
86
|
+
GC.start
|
|
87
|
+
Dispatcher.reset_application!
|
|
88
|
+
ActionController::Routing::Routes.reload
|
|
63
89
|
end
|
|
64
|
-
|
|
65
|
-
# This finalizes the output using the proper HttpResponse way
|
|
66
|
-
cgi.out {""}
|
|
67
|
-
rescue Errno::EPIPE
|
|
68
|
-
# ignored
|
|
69
|
-
rescue Object => rails_error
|
|
70
|
-
STDERR.puts "Error calling Dispatcher.dispatch #{rails_error.inspect}"
|
|
71
|
-
STDERR.puts rails_error.backtrace.join("\n")
|
|
72
90
|
end
|
|
73
91
|
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
92
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
# Creates Rails specific configuration options for people to use
|
|
94
|
+
# instead of the base Configurator.
|
|
95
|
+
class RailsConfigurator < Mongrel::Configurator
|
|
96
|
+
|
|
97
|
+
# Creates a single rails handler and returns it so you
|
|
98
|
+
# can add it to a uri. You can actually attach it to
|
|
99
|
+
# as many URIs as you want, but this returns the
|
|
100
|
+
# same RailsHandler for each call.
|
|
101
|
+
#
|
|
102
|
+
# Requires the following options:
|
|
103
|
+
#
|
|
104
|
+
# * :docroot => The public dir to serve from.
|
|
105
|
+
# * :environment => Rails environment to use.
|
|
106
|
+
# * :cwd => The change to working directory
|
|
107
|
+
#
|
|
108
|
+
# And understands the following optional settings:
|
|
109
|
+
#
|
|
110
|
+
# * :mime => A map of mime types.
|
|
111
|
+
#
|
|
112
|
+
# Because of how Rails is designed you can only have
|
|
113
|
+
# one installed per Ruby interpreter (talk to them
|
|
114
|
+
# about thread safety). Because of this the first
|
|
115
|
+
# time you call this function it does all the config
|
|
116
|
+
# needed to get your rails working. After that
|
|
117
|
+
# it returns the one handler you've configured.
|
|
118
|
+
# This lets you attach Rails to any URI (and mulitple)
|
|
119
|
+
# you want, but still protects you from threads destroying
|
|
120
|
+
# your handler.
|
|
121
|
+
def rails(options={})
|
|
122
|
+
|
|
123
|
+
return @rails_handler if @rails_handler
|
|
124
|
+
|
|
125
|
+
ops = resolve_defaults(options)
|
|
126
|
+
|
|
127
|
+
# fix up some defaults
|
|
128
|
+
ops[:environment] ||= "development"
|
|
129
|
+
ops[:docroot] ||= "public"
|
|
130
|
+
ops[:mime] ||= {}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
$orig_dollar_quote = $".clone
|
|
134
|
+
ENV['RAILS_ENV'] = ops[:environment]
|
|
135
|
+
require "#{ops[:cwd]}/config/environment"
|
|
136
|
+
require 'dispatcher'
|
|
137
|
+
require 'mongrel/rails'
|
|
138
|
+
|
|
139
|
+
@rails_handler = RailsHandler.new(ops[:docroot], ops[:mime])
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# Reloads rails. This isn't too reliable really, but
|
|
144
|
+
# should work for most minimal reload purposes. Only reliable
|
|
145
|
+
# way it so stop then start the process.
|
|
146
|
+
def reload!
|
|
147
|
+
if not @rails_handler
|
|
148
|
+
raise "Rails was not configured. Read the docs for RailsConfigurator."
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
log "Reloading rails..."
|
|
152
|
+
@rails_handler.reload!
|
|
153
|
+
log "Done reloading rails."
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Takes the exact same configuration as Mongrel::Configurator (and actually calls that)
|
|
158
|
+
# but sets up the additional HUP handler to call reload!.
|
|
159
|
+
def setup_rails_signals(options={})
|
|
160
|
+
ops = resolve_defaults(options)
|
|
161
|
+
|
|
162
|
+
if RUBY_PLATFORM !~ /mswin/
|
|
163
|
+
setup_signals(options)
|
|
164
|
+
|
|
165
|
+
# rails reload
|
|
166
|
+
trap("HUP") {
|
|
167
|
+
log "HUP signal received."
|
|
168
|
+
reload!
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
log "Rails signals registered. HUP => reload (without restart). It might not work well."
|
|
172
|
+
else
|
|
173
|
+
log "WARNING: Rails does not support signals on Win32."
|
|
174
|
+
end
|
|
175
|
+
end
|
|
83
176
|
end
|
|
84
177
|
end
|
|
85
178
|
end
|