Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
df387ab3
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
df387ab3
编写于
12月 30, 2013
作者:
C
Charlie Somerville
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
remove FastCGI crap
上级
01189596
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
1 addition
and
538 deletion
+1
-538
actionpack/test/controller/rack_test.rb
actionpack/test/controller/rack_test.rb
+0
-1
railties/Rakefile
railties/Rakefile
+1
-6
railties/dispatches/dispatch.fcgi
railties/dispatches/dispatch.fcgi
+0
-24
railties/lib/fcgi_handler.rb
railties/lib/fcgi_handler.rb
+0
-239
railties/lib/rails_generator/generators/applications/app/app_generator.rb
...ls_generator/generators/applications/app/app_generator.rb
+0
-1
railties/lib/tasks/framework.rake
railties/lib/tasks/framework.rake
+0
-1
railties/test/fcgi_dispatcher_test.rb
railties/test/fcgi_dispatcher_test.rb
+0
-266
未找到文件。
actionpack/test/controller/rack_test.rb
浏览文件 @
df387ab3
...
...
@@ -5,7 +5,6 @@ def setup
@env
=
{
"HTTP_MAX_FORWARDS"
=>
"10"
,
"SERVER_NAME"
=>
"glu.ttono.us"
,
"FCGI_ROLE"
=>
"RESPONDER"
,
"AUTH_TYPE"
=>
"Basic"
,
"HTTP_X_FORWARDED_HOST"
=>
"glu.ttono.us"
,
"HTTP_ACCEPT_CHARSET"
=>
"UTF-8"
,
...
...
railties/Rakefile
浏览文件 @
df387ab3
...
...
@@ -159,14 +159,9 @@ end
desc
"Make copies of all the default content of ties"
task
:copy_ties_content
=>
[
:copy_rootfiles
,
:copy_
dispatches
,
:copy_
html_files
,
:copy_application
,
:copy_rootfiles
,
:copy_html_files
,
:copy_application
,
:copy_configs
,
:copy_binfiles
,
:copy_test_helpers
,
:copy_app_doc_readme
]
task
:copy_dispatches
do
copy_with_rewritten_ruby_path
(
"dispatches/dispatch.fcgi"
,
"
#{
PKG_DESTINATION
}
/public/dispatch.fcgi"
)
chmod
0755
,
"
#{
PKG_DESTINATION
}
/public/dispatch.fcgi"
end
task
:copy_html_files
do
HTML_FILES
.
each
{
|
file
|
cp
File
.
join
(
'html'
,
file
),
File
.
join
(
PKG_DESTINATION
,
'public'
,
file
)
}
end
...
...
railties/dispatches/dispatch.fcgi
已删除
100755 → 0
浏览文件 @
01189596
#!/usr/bin/env ruby
#
# You may specify the path to the FastCGI crash log (a log of unhandled
# exceptions which forced the FastCGI instance to exit, great for debugging)
# and the number of requests to process before running garbage collection.
#
# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
# and the GC period is nil (turned off). A reasonable number of requests
# could range from 10-100 depending on the memory footprint of your app.
#
# Example:
# # Default log path, normal GC behavior.
# RailsFCGIHandler.process!
#
# # Default log path, 50 requests between GC.
# RailsFCGIHandler.process! nil, 50
#
# # Custom log path, normal GC behavior.
# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
#
require
File
.
dirname
(
__FILE__
)
+
"/../config/environment"
require
'fcgi_handler'
RailsFCGIHandler
.
process!
railties/lib/fcgi_handler.rb
已删除
100644 → 0
浏览文件 @
01189596
require
'fcgi'
require
'logger'
require
'dispatcher'
require
'rbconfig'
class
RailsFCGIHandler
SIGNALS
=
{
'HUP'
=>
:reload
,
'INT'
=>
:exit_now
,
'TERM'
=>
:exit_now
,
'USR1'
=>
:exit
,
'USR2'
=>
:restart
}
GLOBAL_SIGNALS
=
SIGNALS
.
keys
-
%w(USR1)
attr_reader
:when_ready
attr_accessor
:log_file_path
attr_accessor
:gc_request_period
# Initialize and run the FastCGI instance, passing arguments through to new.
def
self
.
process!
(
*
args
,
&
block
)
new
(
*
args
,
&
block
).
process!
end
# 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.
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
@app
=
Dispatcher
.
new
# Start error timestamp at 11 seconds ago.
@last_error_on
=
Time
.
now
-
11
end
def
process!
(
provider
=
FCGI
)
mark_features!
dispatcher_log
:info
,
'starting'
process_each_request
provider
dispatcher_log
:info
,
'stopping gracefully'
rescue
Exception
=>
error
case
error
when
SystemExit
dispatcher_log
:info
,
'stopping after explicit exit'
when
SignalException
dispatcher_error
error
,
'stopping after unhandled signal'
else
# Retry if exceptions occur more than 10 seconds apart.
if
Time
.
now
-
@last_error_on
>
10
@last_error_on
=
Time
.
now
dispatcher_error
error
,
'retrying after unhandled exception'
retry
else
dispatcher_error
error
,
'stopping after unhandled exception within 10 seconds of the last'
end
end
end
protected
def
process_each_request
(
provider
)
request
=
nil
catch
:exit
do
provider
.
each
do
|
request
|
process_request
(
request
)
case
when_ready
when
:reload
reload!
when
:restart
close_connection
(
request
)
restart!
when
:exit
close_connection
(
request
)
throw
:exit
end
end
end
rescue
SignalException
=>
signal
raise
unless
signal
.
message
==
'SIGUSR1'
close_connection
(
request
)
end
def
process_request
(
request
)
@processing
,
@when_ready
=
true
,
nil
gc_countdown
with_signal_handler
'USR1'
do
begin
::
Rack
::
Handler
::
FastCGI
.
serve
(
request
,
@app
)
rescue
SignalException
,
SystemExit
raise
rescue
Exception
=>
error
dispatcher_error
error
,
'unhandled dispatch error'
end
end
ensure
@processing
=
false
end
def
logger
@logger
||=
Logger
.
new
(
@log_file_path
)
end
def
dispatcher_log
(
level
,
msg
)
time_str
=
Time
.
now
.
strftime
(
"%d/%b/%Y:%H:%M:%S"
)
logger
.
send
(
level
,
"[
#{
time_str
}
::
#{
$$
}
]
#{
msg
}
"
)
rescue
Exception
=>
log_error
# Logger errors
STDERR
<<
"Couldn't write to
#{
@log_file_path
.
inspect
}
:
#{
msg
}
\n
"
STDERR
<<
"
#{
log_error
.
class
}
:
#{
log_error
.
message
}
\n
"
end
def
dispatcher_error
(
e
,
msg
=
""
)
error_message
=
"Dispatcher failed to catch:
#{
e
}
(
#{
e
.
class
}
)
\n
"
+
"
#{
e
.
backtrace
.
join
(
"
\n
"
)
}
\n
#{
msg
}
"
dispatcher_log
(
:error
,
error_message
)
end
def
install_signal_handlers
GLOBAL_SIGNALS
.
each
{
|
signal
|
install_signal_handler
(
signal
)
}
end
def
install_signal_handler
(
signal
,
handler
=
nil
)
if
SIGNALS
.
include?
(
signal
)
&&
self
.
class
.
method_defined?
(
name
=
"
#{
SIGNALS
[
signal
]
}
_handler"
)
handler
||=
method
(
name
).
to_proc
begin
trap
(
signal
,
handler
)
rescue
ArgumentError
dispatcher_log
:warn
,
"Ignoring unsupported signal
#{
signal
}
."
end
else
dispatcher_log
:warn
,
"Ignoring unsupported signal
#{
signal
}
."
end
end
def
with_signal_handler
(
signal
)
install_signal_handler
(
signal
)
yield
ensure
install_signal_handler
(
signal
,
'DEFAULT'
)
end
def
exit_now_handler
(
signal
)
dispatcher_log
:info
,
"asked to stop immediately"
exit
end
def
exit_handler
(
signal
)
dispatcher_log
:info
,
"asked to stop ASAP"
if
@processing
@when_ready
=
:exit
else
throw
:exit
end
end
def
reload_handler
(
signal
)
dispatcher_log
:info
,
"asked to reload ASAP"
if
@processing
@when_ready
=
:reload
else
reload!
end
end
def
restart_handler
(
signal
)
dispatcher_log
:info
,
"asked to restart ASAP"
if
@processing
@when_ready
=
:restart
else
restart!
end
end
def
restart!
config
=
::
Config
::
CONFIG
ruby
=
File
::
join
(
config
[
'bindir'
],
config
[
'ruby_install_name'
])
+
config
[
'EXEEXT'
]
command_line
=
[
ruby
,
$0
,
ARGV
].
flatten
.
join
(
' '
)
dispatcher_log
:info
,
"restarted"
# close resources as they won't be closed by
# the OS when using exec
logger
.
close
rescue
nil
Rails
.
logger
.
close
rescue
nil
exec
(
command_line
)
end
def
reload!
run_gc!
if
gc_request_period
restore!
@when_ready
=
nil
dispatcher_log
:info
,
"reloaded"
end
# Make a note of $" so we can safely reload this instance.
def
mark_features!
@features
=
$"
.
clone
end
def
restore!
$"
.
replace
@features
Dispatcher
.
reset_application!
ActionController
::
Routing
::
Routes
.
reload
end
def
run_gc!
@gc_request_countdown
=
gc_request_period
GC
.
enable
;
GC
.
start
;
GC
.
disable
end
def
gc_countdown
if
gc_request_period
@gc_request_countdown
||=
gc_request_period
@gc_request_countdown
-=
1
run_gc!
if
@gc_request_countdown
<=
0
end
end
def
close_connection
(
request
)
request
.
finish
if
request
end
end
railties/lib/rails_generator/generators/applications/app/app_generator.rb
浏览文件 @
df387ab3
...
...
@@ -218,7 +218,6 @@ def create_dispatch_files(m)
dispatcher_options
=
{
:chmod
=>
0755
,
:shebang
=>
options
[
:shebang
]
}
m
.
file
"dispatches/config.ru"
,
"config.ru"
m
.
file
"dispatches/dispatch.fcgi"
,
"public/dispatch.fcgi"
,
dispatcher_options
end
end
...
...
railties/lib/tasks/framework.rake
浏览文件 @
df387ab3
...
...
@@ -138,7 +138,6 @@ namespace :rails do
task
:generate_dispatchers
do
require
'railties_path'
FileUtils
.
cp
(
RAILTIES_PATH
+
'/dispatches/config.ru'
,
RAILS_ROOT
+
'/config.ru'
)
FileUtils
.
cp
(
RAILTIES_PATH
+
'/dispatches/dispatch.fcgi'
,
RAILS_ROOT
+
'/public/dispatch.fcgi'
)
end
end
end
railties/test/fcgi_dispatcher_test.rb
已删除
100644 → 0
浏览文件 @
01189596
require
'abstract_unit'
if
RUBY_VERSION
<
'1.9.0'
uses_gem
"fcgi"
,
"0.8.7"
do
require
'action_controller'
require
'fcgi_handler'
Dispatcher
.
middleware
.
clear
class
RailsFCGIHandlerTest
<
Test
::
Unit
::
TestCase
def
setup
@log
=
StringIO
.
new
@handler
=
RailsFCGIHandler
.
new
(
@log
)
end
def
test_process_restart
request
=
mock
FCGI
.
stubs
(
:each
).
yields
(
request
)
@handler
.
expects
(
:process_request
).
once
@handler
.
expects
(
:dispatcher_error
).
never
@handler
.
expects
(
:when_ready
).
returns
(
:restart
)
@handler
.
expects
(
:close_connection
).
with
(
request
)
@handler
.
expects
(
:reload!
).
never
@handler
.
expects
(
:restart!
)
@handler
.
process!
end
def
test_process_exit
request
=
mock
FCGI
.
stubs
(
:each
).
yields
(
request
)
@handler
.
expects
(
:process_request
).
once
@handler
.
expects
(
:dispatcher_error
).
never
@handler
.
expects
(
:when_ready
).
returns
(
:exit
)
@handler
.
expects
(
:close_connection
).
with
(
request
)
@handler
.
expects
(
:reload!
).
never
@handler
.
expects
(
:restart!
).
never
@handler
.
process!
end
def
test_process_with_system_exit_exception
request
=
mock
FCGI
.
stubs
(
:each
).
yields
(
request
)
@handler
.
expects
(
:process_request
).
once
.
raises
(
SystemExit
)
@handler
.
stubs
(
:dispatcher_log
)
@handler
.
expects
(
:dispatcher_log
).
with
(
:info
,
regexp_matches
(
/^stopping/
))
@handler
.
expects
(
:dispatcher_error
).
never
@handler
.
expects
(
:when_ready
).
never
@handler
.
expects
(
:close_connection
).
never
@handler
.
expects
(
:reload!
).
never
@handler
.
expects
(
:restart!
).
never
@handler
.
process!
end
def
test_restart_handler_outside_request
@handler
.
expects
(
:dispatcher_log
).
with
(
:info
,
"asked to restart ASAP"
)
@handler
.
expects
(
:restart!
).
once
@handler
.
send
(
:restart_handler
,
nil
)
assert_equal
nil
,
@handler
.
when_ready
end
def
test_install_signal_handler_should_log_on_bad_signal
@handler
.
stubs
(
:trap
).
raises
(
ArgumentError
)
@handler
.
expects
(
:dispatcher_log
).
with
(
:warn
,
"Ignoring unsupported signal CHEESECAKE."
)
@handler
.
send
(
:install_signal_handler
,
"CHEESECAKE"
,
nil
)
end
def
test_reload
@handler
.
expects
(
:restore!
)
@handler
.
expects
(
:dispatcher_log
).
with
(
:info
,
"reloaded"
)
@handler
.
send
(
:reload!
)
assert_nil
@handler
.
when_ready
end
def
test_reload_runs_gc_when_gc_request_period_set
@handler
.
expects
(
:run_gc!
)
@handler
.
expects
(
:restore!
)
@handler
.
expects
(
:dispatcher_log
).
with
(
:info
,
"reloaded"
)
@handler
.
gc_request_period
=
10
@handler
.
send
(
:reload!
)
end
def
test_reload_doesnt_run_gc_if_gc_request_period_isnt_set
@handler
.
expects
(
:run_gc!
).
never
@handler
.
expects
(
:restore!
)
@handler
.
expects
(
:dispatcher_log
).
with
(
:info
,
"reloaded"
)
@handler
.
send
(
:reload!
)
end
def
test_restart!
@handler
.
expects
(
:dispatcher_log
).
with
(
:info
,
"restarted"
)
@handler
.
expects
(
:exec
).
returns
(
'restarted'
)
assert_equal
'restarted'
,
@handler
.
send
(
:restart!
)
end
def
test_restore!
$"
.
expects
(
:replace
)
Dispatcher
.
expects
(
:reset_application!
)
ActionController
::
Routing
::
Routes
.
expects
(
:reload
)
@handler
.
send
(
:restore!
)
end
def
test_uninterrupted_processing
request
=
mock
FCGI
.
expects
(
:each
).
yields
(
request
)
@handler
.
expects
(
:process_request
).
with
(
request
)
@handler
.
process!
assert_nil
@handler
.
when_ready
end
end
class
RailsFCGIHandlerSignalsTest
<
Test
::
Unit
::
TestCase
class
::
RailsFCGIHandler
attr_accessor
:signal
alias_method
:old_gc_countdown
,
:gc_countdown
def
gc_countdown
signal
?
Process
.
kill
(
signal
,
$$
)
:
old_gc_countdown
end
end
def
setup
@log
=
StringIO
.
new
@handler
=
RailsFCGIHandler
.
new
(
@log
)
@dispatcher
=
mock
Dispatcher
.
stubs
(
:new
).
returns
(
@dispatcher
)
end
def
test_interrupted_via_HUP_when_not_in_request
request
=
mock
FCGI
.
expects
(
:each
).
once
.
yields
(
request
)
@handler
.
expects
(
:signal
).
times
(
2
).
returns
(
'HUP'
)
@handler
.
expects
(
:reload!
).
once
@handler
.
expects
(
:close_connection
).
never
@handler
.
expects
(
:exit
).
never
@handler
.
process!
assert_equal
:reload
,
@handler
.
when_ready
end
def
test_interrupted_via_USR1_when_not_in_request
request
=
mock
FCGI
.
expects
(
:each
).
once
.
yields
(
request
)
@handler
.
expects
(
:signal
).
times
(
2
).
returns
(
'USR1'
)
@handler
.
expects
(
:exit_handler
).
never
@handler
.
expects
(
:reload!
).
never
@handler
.
expects
(
:close_connection
).
with
(
request
).
once
@handler
.
expects
(
:exit
).
never
@handler
.
process!
assert_nil
@handler
.
when_ready
end
def
test_restart_via_USR2_when_in_request
request
=
mock
FCGI
.
expects
(
:each
).
once
.
yields
(
request
)
@handler
.
expects
(
:signal
).
times
(
2
).
returns
(
'USR2'
)
@handler
.
expects
(
:exit_handler
).
never
@handler
.
expects
(
:reload!
).
never
@handler
.
expects
(
:close_connection
).
with
(
request
).
once
@handler
.
expects
(
:exit
).
never
@handler
.
expects
(
:restart!
).
once
@handler
.
process!
assert_equal
:restart
,
@handler
.
when_ready
end
def
test_interrupted_via_TERM
request
=
mock
FCGI
.
expects
(
:each
).
once
.
yields
(
request
)
::
Rack
::
Handler
::
FastCGI
.
expects
(
:serve
).
once
.
returns
(
'TERM'
)
@handler
.
expects
(
:reload!
).
never
@handler
.
expects
(
:close_connection
).
never
@handler
.
process!
assert_nil
@handler
.
when_ready
end
def
test_runtime_exception_in_fcgi
error
=
RuntimeError
.
new
(
'foo'
)
FCGI
.
expects
(
:each
).
times
(
2
).
raises
(
error
)
@handler
.
expects
(
:dispatcher_error
).
with
(
error
,
regexp_matches
(
/^retrying/
))
@handler
.
expects
(
:dispatcher_error
).
with
(
error
,
regexp_matches
(
/^stopping/
))
@handler
.
process!
end
def
test_runtime_error_in_dispatcher
request
=
mock
error
=
RuntimeError
.
new
(
'foo'
)
FCGI
.
expects
(
:each
).
once
.
yields
(
request
)
::
Rack
::
Handler
::
FastCGI
.
expects
(
:serve
).
once
.
raises
(
error
)
@handler
.
expects
(
:dispatcher_error
).
with
(
error
,
regexp_matches
(
/^unhandled/
))
@handler
.
process!
end
def
test_signal_exception_in_fcgi
error
=
SignalException
.
new
(
'USR2'
)
FCGI
.
expects
(
:each
).
once
.
raises
(
error
)
@handler
.
expects
(
:dispatcher_error
).
with
(
error
,
regexp_matches
(
/^stopping/
))
@handler
.
process!
end
def
test_signal_exception_in_dispatcher
request
=
mock
error
=
SignalException
.
new
(
'USR2'
)
FCGI
.
expects
(
:each
).
once
.
yields
(
request
)
::
Rack
::
Handler
::
FastCGI
.
expects
(
:serve
).
once
.
raises
(
error
)
@handler
.
expects
(
:dispatcher_error
).
with
(
error
,
regexp_matches
(
/^stopping/
))
@handler
.
process!
end
end
class
RailsFCGIHandlerPeriodicGCTest
<
Test
::
Unit
::
TestCase
def
setup
@log
=
StringIO
.
new
end
def
teardown
GC
.
enable
end
def
test_normal_gc
@handler
=
RailsFCGIHandler
.
new
(
@log
)
assert_nil
@handler
.
gc_request_period
# When GC is enabled, GC.disable disables and returns false.
assert_equal
false
,
GC
.
disable
end
def
test_periodic_gc
@handler
=
RailsFCGIHandler
.
new
(
@log
,
10
)
assert_equal
10
,
@handler
.
gc_request_period
request
=
mock
FCGI
.
expects
(
:each
).
times
(
10
).
yields
(
request
)
@handler
.
expects
(
:run_gc!
).
never
9
.
times
{
@handler
.
process!
}
@handler
.
expects
(
:run_gc!
).
once
@handler
.
process!
assert_nil
@handler
.
when_ready
end
end
end
# uses_gem "fcgi"
end
# exclude 1.9
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录