mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Final tweaks to speed up the file serving a bit using sendfile and a modified file handler.
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@124 19e92222-5c0b-0410-8929-a290d50e31e9
This commit is contained in:
parent
4d9966ee00
commit
110e92752b
4 changed files with 253 additions and 216 deletions
|
@ -4,6 +4,7 @@
|
|||
# This is where Win32::Daemon resides.
|
||||
###############################################
|
||||
require 'rubygems'
|
||||
require 'mongrel'
|
||||
require 'mongrel/rails'
|
||||
require 'optparse'
|
||||
require 'win32/service'
|
||||
|
@ -70,14 +71,15 @@ class MongrelRails
|
|||
|
||||
def delayed_initialize
|
||||
dbg "delayed_initialize entered"
|
||||
|
||||
|
||||
@rails = configure_rails
|
||||
|
||||
# start up mongrel with the right configurations
|
||||
@server = Mongrel::HttpServer.new(@ip, @port, @num_procs.to_i, @timeout.to_i)
|
||||
@server.register("/", @rails)
|
||||
|
||||
|
||||
dbg "delayed_initialize left"
|
||||
|
||||
end
|
||||
|
||||
def load_mime_map
|
||||
|
@ -104,11 +106,12 @@ class MongrelRails
|
|||
|
||||
Dir.chdir(@rails_root)
|
||||
|
||||
|
||||
ENV['RAILS_ENV'] = @environment
|
||||
require File.join(@rails_root, 'config/environment')
|
||||
require 'config/environment'
|
||||
|
||||
# configure the rails handler
|
||||
rails = RailsHandler.new(@docroot, load_mime_map)
|
||||
rails = Mongrel::Rails::RailsHandler.new(@docroot, load_mime_map)
|
||||
|
||||
dbg "configure_rails left"
|
||||
|
||||
|
@ -116,24 +119,29 @@ class MongrelRails
|
|||
end
|
||||
|
||||
def start_serve
|
||||
dbg "start_serve entered"
|
||||
|
||||
@runner = Thread.new do
|
||||
dbg_th "runner_thread suspended"
|
||||
Thread.stop
|
||||
begin
|
||||
dbg "start_serve entered"
|
||||
|
||||
dbg_th "runner_thread resumed"
|
||||
dbg_th "runner_thread acceptor.join"
|
||||
@server.acceptor.join
|
||||
@runner = Thread.new do
|
||||
dbg_th "runner_thread suspended"
|
||||
Thread.stop
|
||||
|
||||
dbg_th "runner_thread resumed"
|
||||
dbg_th "runner_thread acceptor.join"
|
||||
@server.acceptor.join
|
||||
end
|
||||
|
||||
dbg "server.run"
|
||||
@server.run
|
||||
|
||||
dbg "runner.run"
|
||||
@runner.run
|
||||
|
||||
dbg "start_serve left"
|
||||
rescue
|
||||
dbg "ERROR: #$!\r\n"
|
||||
dbg $!.backtrace.join("\r\n")
|
||||
end
|
||||
|
||||
dbg "server.run"
|
||||
@server.run
|
||||
|
||||
dbg "runner.run"
|
||||
@runner.run
|
||||
|
||||
dbg "start_serve left"
|
||||
end
|
||||
|
||||
def stop_serve
|
||||
|
@ -193,99 +201,107 @@ class RailsDaemon < Win32::Daemon
|
|||
end
|
||||
|
||||
|
||||
if ARGV[0] == 'service'
|
||||
ARGV.shift
|
||||
|
||||
# default options
|
||||
OPTIONS = {
|
||||
:rails_root => Dir.pwd,
|
||||
:environment => 'production',
|
||||
:ip => '0.0.0.0',
|
||||
:port => 3000,
|
||||
:mime_map => nil,
|
||||
:num_procs => 1024,
|
||||
:timeout => 0,
|
||||
:cpu => nil
|
||||
}
|
||||
|
||||
ARGV.options do |opts|
|
||||
opts.on('-r', '--root PATH', "Set the root path where your rails app resides.") { |OPTIONS[:rails_root]| }
|
||||
opts.on('-e', '--environment ENV', "Rails environment to run as. (default: production)") { |OPTIONS[:environment]| }
|
||||
opts.on('-b', '--binding ADDR', "Address to bind to") { |OPTIONS[:ip]| }
|
||||
opts.on('-p', '--port PORT', "Which port to bind to") { |OPTIONS[:port]| }
|
||||
opts.on('-m', '--mime PATH', "A YAML file that lists additional MIME types") { |OPTIONS[:mime_map]| }
|
||||
opts.on('-P', '--num-procs INT', "Number of processor threads to use") { |OPTIONS[:num_procs]| }
|
||||
opts.on('-t', '--timeout SECONDS', "Timeout all requests after SECONDS time") { |OPTIONS[:timeout]| }
|
||||
opts.on('-c', '--cpu CPU', "Bind the process to specific cpu") { |OPTIONS[:cpu]| }
|
||||
|
||||
opts.parse!
|
||||
end
|
||||
|
||||
#expand RAILS_ROOT
|
||||
OPTIONS[:rails_root] = File.expand_path(OPTIONS[:rails_root])
|
||||
|
||||
OPTIONS[:docroot] = File.expand_path(OPTIONS[:rails_root] + '/public')
|
||||
|
||||
# We must bind to a specific cpu?
|
||||
if OPTIONS[:cpu]
|
||||
Kernel32.set_affinity(Process.pid, OPTIONS[:cpu])
|
||||
end
|
||||
|
||||
rails = MongrelRails.new(OPTIONS[:ip], OPTIONS[:port], OPTIONS[:rails_root], OPTIONS[:docroot], OPTIONS[:environment], OPTIONS[:mime_map], OPTIONS[:num_procs].to_i, OPTIONS[:timeout].to_i)
|
||||
rails_svc = RailsDaemon.new(rails)
|
||||
rails_svc.mainloop
|
||||
|
||||
elsif ARGV[0] == 'debug'
|
||||
ARGV.shift
|
||||
|
||||
# default options
|
||||
OPTIONS = {
|
||||
:rails_root => Dir.pwd,
|
||||
:environment => 'production',
|
||||
:ip => '0.0.0.0',
|
||||
:port => 3000,
|
||||
:mime_map => nil,
|
||||
:num_procs => 20,
|
||||
:timeout => 120,
|
||||
:cpu => nil
|
||||
}
|
||||
|
||||
ARGV.options do |opts|
|
||||
opts.on('-r', '--root PATH', "Set the root path where your rails app resides.") { |OPTIONS[:rails_root]| }
|
||||
opts.on('-e', '--environment ENV', "Rails environment to run as.") { |OPTIONS[:environment]| }
|
||||
opts.on('-b', '--binding ADDR', "Address to bind to") { |OPTIONS[:ip]| }
|
||||
opts.on('-p', '--port PORT', "Which port to bind to") { |OPTIONS[:port]| }
|
||||
opts.on('-m', '--mime PATH', "A YAML file that lists additional MIME types") { |OPTIONS[:mime_map]| }
|
||||
opts.on('-P', '--num-procs INT', "Number of processor threads to use") { |OPTIONS[:num_procs]| }
|
||||
opts.on('-t', '--timeout SECONDS', "Timeout all requests after SECONDS time") { |OPTIONS[:timeout]| }
|
||||
opts.on('-c', '--cpu CPU', "Bind the process to specific cpu") { |OPTIONS[:cpu]| }
|
||||
|
||||
opts.parse!
|
||||
end
|
||||
|
||||
#expand RAILS_ROOT
|
||||
OPTIONS[:rails_root] = File.expand_path(OPTIONS[:rails_root])
|
||||
|
||||
OPTIONS[:docroot] = File.expand_path(OPTIONS[:rails_root] + '/public')
|
||||
|
||||
# We must bind to a specific cpu?
|
||||
if OPTIONS[:cpu]
|
||||
Kernel32.set_affinity(Process.pid, OPTIONS[:cpu])
|
||||
end
|
||||
|
||||
rails = MongrelRails.new(OPTIONS[:ip], OPTIONS[:port], OPTIONS[:rails_root], OPTIONS[:docroot], OPTIONS[:environment], OPTIONS[:mime_map], OPTIONS[:num_procs].to_i, OPTIONS[:timeout].to_i)
|
||||
rails.delayed_initialize
|
||||
rails.start_serve
|
||||
|
||||
begin
|
||||
sleep
|
||||
rescue Interrupt
|
||||
puts "graceful shutdown?"
|
||||
end
|
||||
|
||||
begin
|
||||
rails.stop_serve
|
||||
rescue
|
||||
end
|
||||
|
||||
begin
|
||||
if ARGV[0] == 'service'
|
||||
ARGV.shift
|
||||
|
||||
# default options
|
||||
OPTIONS = {
|
||||
:rails_root => Dir.pwd,
|
||||
:environment => 'production',
|
||||
:ip => '0.0.0.0',
|
||||
:port => 3000,
|
||||
:mime_map => nil,
|
||||
:num_procs => 1024,
|
||||
:timeout => 0,
|
||||
:cpu => nil
|
||||
}
|
||||
|
||||
ARGV.options do |opts|
|
||||
opts.on('-r', '--root PATH', "Set the root path where your rails app resides.") { |OPTIONS[:rails_root]| }
|
||||
opts.on('-e', '--environment ENV', "Rails environment to run as. (default: production)") { |OPTIONS[:environment]| }
|
||||
opts.on('-b', '--binding ADDR', "Address to bind to") { |OPTIONS[:ip]| }
|
||||
opts.on('-p', '--port PORT', "Which port to bind to") { |OPTIONS[:port]| }
|
||||
opts.on('-m', '--mime PATH', "A YAML file that lists additional MIME types") { |OPTIONS[:mime_map]| }
|
||||
opts.on('-P', '--num-procs INT', "Number of processor threads to use") { |OPTIONS[:num_procs]| }
|
||||
opts.on('-t', '--timeout SECONDS', "Timeout all requests after SECONDS time") { |OPTIONS[:timeout]| }
|
||||
opts.on('-c', '--cpu CPU', "Bind the process to specific cpu") { |OPTIONS[:cpu]| }
|
||||
|
||||
opts.parse!
|
||||
end
|
||||
|
||||
#expand RAILS_ROOT
|
||||
OPTIONS[:rails_root] = File.expand_path(OPTIONS[:rails_root])
|
||||
|
||||
OPTIONS[:docroot] = File.expand_path(OPTIONS[:rails_root] + '/public')
|
||||
|
||||
# We must bind to a specific cpu?
|
||||
if OPTIONS[:cpu]
|
||||
Kernel32.set_affinity(Process.pid, OPTIONS[:cpu])
|
||||
end
|
||||
|
||||
rails = MongrelRails.new(OPTIONS[:ip], OPTIONS[:port], OPTIONS[:rails_root], OPTIONS[:docroot], OPTIONS[:environment], OPTIONS[:mime_map], OPTIONS[:num_procs].to_i, OPTIONS[:timeout].to_i)
|
||||
rails_svc = RailsDaemon.new(rails)
|
||||
rails_svc.mainloop
|
||||
|
||||
elsif ARGV[0] == 'debug'
|
||||
ARGV.shift
|
||||
|
||||
# default options
|
||||
OPTIONS = {
|
||||
:rails_root => Dir.pwd,
|
||||
:environment => 'production',
|
||||
:ip => '0.0.0.0',
|
||||
:port => 3000,
|
||||
:mime_map => nil,
|
||||
:num_procs => 20,
|
||||
:timeout => 120,
|
||||
:cpu => nil
|
||||
}
|
||||
|
||||
ARGV.options do |opts|
|
||||
opts.on('-r', '--root PATH', "Set the root path where your rails app resides.") { |OPTIONS[:rails_root]| }
|
||||
opts.on('-e', '--environment ENV', "Rails environment to run as.") { |OPTIONS[:environment]| }
|
||||
opts.on('-b', '--binding ADDR', "Address to bind to") { |OPTIONS[:ip]| }
|
||||
opts.on('-p', '--port PORT', "Which port to bind to") { |OPTIONS[:port]| }
|
||||
opts.on('-m', '--mime PATH', "A YAML file that lists additional MIME types") { |OPTIONS[:mime_map]| }
|
||||
opts.on('-P', '--num-procs INT', "Number of processor threads to use") { |OPTIONS[:num_procs]| }
|
||||
opts.on('-t', '--timeout SECONDS', "Timeout all requests after SECONDS time") { |OPTIONS[:timeout]| }
|
||||
opts.on('-c', '--cpu CPU', "Bind the process to specific cpu") { |OPTIONS[:cpu]| }
|
||||
|
||||
opts.parse!
|
||||
end
|
||||
|
||||
#expand RAILS_ROOT
|
||||
OPTIONS[:rails_root] = File.expand_path(OPTIONS[:rails_root])
|
||||
|
||||
OPTIONS[:docroot] = File.expand_path(OPTIONS[:rails_root] + '/public')
|
||||
|
||||
# We must bind to a specific cpu?
|
||||
if OPTIONS[:cpu]
|
||||
Kernel32.set_affinity(Process.pid, OPTIONS[:cpu])
|
||||
end
|
||||
|
||||
rails = MongrelRails.new(OPTIONS[:ip], OPTIONS[:port], OPTIONS[:rails_root], OPTIONS[:docroot], OPTIONS[:environment], OPTIONS[:mime_map], OPTIONS[:num_procs].to_i, OPTIONS[:timeout].to_i)
|
||||
rails.delayed_initialize
|
||||
rails.start_serve
|
||||
|
||||
begin
|
||||
sleep
|
||||
rescue Interrupt
|
||||
dbg "ERROR: #$!\r\n"
|
||||
dbg $!.backtrace.join("\r\n")
|
||||
puts "graceful shutdown?"
|
||||
end
|
||||
|
||||
begin
|
||||
rails.stop_serve
|
||||
rescue
|
||||
dbg "ERROR: #$!\r\n"
|
||||
dbg $!.backtrace.join("\r\n")
|
||||
end
|
||||
end
|
||||
rescue
|
||||
dbg "ERROR: #$!\r\n"
|
||||
dbg $!.backtrace.join("\r\n")
|
||||
end
|
||||
|
|
|
@ -200,6 +200,7 @@ module Mongrel
|
|||
@out.write(value)
|
||||
@out.write("\r\n")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Writes and controls your response to the client using the HTTP/1.1 specification.
|
||||
|
@ -306,6 +307,10 @@ module Mongrel
|
|||
end
|
||||
end
|
||||
|
||||
def write(data)
|
||||
@socket.write(data)
|
||||
end
|
||||
|
||||
# This takes whatever has been done to header and body and then writes it in the
|
||||
# proper format to make an HTTP/1.1 response.
|
||||
def finished
|
||||
|
@ -317,6 +322,7 @@ module Mongrel
|
|||
def done
|
||||
(@status_sent and @header_sent and @body_sent)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
require 'rubygems'
|
||||
begin
|
||||
require 'sendfile'
|
||||
$mongrel_has_sendfile = true
|
||||
STDERR.puts "** You have sendfile installed, will use that to serve files."
|
||||
rescue Object
|
||||
$mongrel_has_sendfile = false
|
||||
end
|
||||
|
||||
module Mongrel
|
||||
|
||||
|
@ -150,20 +158,29 @@ module Mongrel
|
|||
# Sends the contents of a file back to the user. Not terribly efficient since it's
|
||||
# opening and closing the file for each read.
|
||||
def send_file(req, response)
|
||||
response.start(200) do |head,out|
|
||||
# set the mime type from our map based on the ending
|
||||
dot_at = req.rindex(".")
|
||||
if dot_at
|
||||
ext = req[dot_at .. -1]
|
||||
if MIME_TYPES[ext]
|
||||
head['Content-Type'] = MIME_TYPES[ext]
|
||||
end
|
||||
end
|
||||
|
||||
open(req, "rb") do |f|
|
||||
out.write(f.read)
|
||||
# first we setup the headers and status then we do a very fast send on the socket directly
|
||||
response.status = 200
|
||||
|
||||
# set the mime type from our map based on the ending
|
||||
dot_at = req.rindex(".")
|
||||
if dot_at
|
||||
ext = req[dot_at .. -1]
|
||||
if MIME_TYPES[ext]
|
||||
response.header['Content-Type'] = MIME_TYPES[ext]
|
||||
end
|
||||
end
|
||||
|
||||
response.header['Content-Length'] = File.size(req)
|
||||
|
||||
response.send_status
|
||||
response.send_header
|
||||
|
||||
if $mongrel_has_sendfile
|
||||
File.open(req, "rb") { |f| response.socket.sendfile(f) }
|
||||
else
|
||||
File.open(req, "rb") { |f| response.socket.write(f.read) }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -184,11 +201,8 @@ module Mongrel
|
|||
send_file(req, response)
|
||||
end
|
||||
rescue => details
|
||||
response.reset
|
||||
response.start(403) do |head,out|
|
||||
out << "Error accessing file: #{details}"
|
||||
out << details.backtrace.join("\n")
|
||||
end
|
||||
STDERR.puts "Error accessing file: #{details}"
|
||||
STDERR.puts details.backtrace.join("\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,92 @@ require 'cgi'
|
|||
module Mongrel
|
||||
module Rails
|
||||
|
||||
|
||||
# Implements a handler that can run Rails and serve files out of the
|
||||
# Rails application's public directory. This lets you run your Rails
|
||||
# application with Mongrel during development and testing, then use it
|
||||
# also in production behind a server that's better at serving the
|
||||
# static files.
|
||||
#
|
||||
# The RailsHandler takes a mime_map parameter which is a simple suffix=mimetype
|
||||
# mapping that it should add to the list of valid mime types.
|
||||
#
|
||||
# It also supports page caching directly and will try to resolve a request
|
||||
# in the following order:
|
||||
#
|
||||
# * If the requested exact PATH_INFO exists as a file then serve it.
|
||||
# * If it exists at PATH_INFO+".html" exists then serve that.
|
||||
# * Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispath to have Rails go.
|
||||
#
|
||||
# This means that if you are using page caching it will actually work with Mongrel
|
||||
# and you should see a decent speed boost (but not as fast as if you use lighttpd).
|
||||
#
|
||||
# An additional feature you can use is
|
||||
class RailsHandler < Mongrel::HttpHandler
|
||||
attr_reader :files
|
||||
attr_reader :guard
|
||||
|
||||
def initialize(dir, mime_map = {})
|
||||
@files = Mongrel::DirHandler.new(dir,false)
|
||||
@guard = Mutex.new
|
||||
|
||||
# register the requested mime types
|
||||
mime_map.each {|k,v| Mongrel::DirHandler::add_mime_type(k,v) }
|
||||
end
|
||||
|
||||
# Attempts to resolve the request as follows:
|
||||
#
|
||||
#
|
||||
# * If the requested exact PATH_INFO exists as a file then serve it.
|
||||
# * If it exists at PATH_INFO+".html" exists then serve that.
|
||||
# * Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispath to have Rails go.
|
||||
def process(request, response)
|
||||
return if response.socket.closed?
|
||||
|
||||
path_info = request.params[Mongrel::Const::PATH_INFO]
|
||||
page_cached = request.params[Mongrel::Const::PATH_INFO] + ".html"
|
||||
|
||||
if @files.can_serve(path_info)
|
||||
# File exists as-is so serve it up
|
||||
@files.process(request,response)
|
||||
elsif @files.can_serve(page_cached)
|
||||
# possible cached page, serve it up
|
||||
request.params[Mongrel::Const::PATH_INFO] = page_cached
|
||||
@files.process(request,response)
|
||||
else
|
||||
begin
|
||||
cgi = Mongrel::CGIWrapper.new(request, response)
|
||||
cgi.handler = self
|
||||
|
||||
@guard.synchronize do
|
||||
# Rails is not thread safe so must be run entirely within synchronize
|
||||
Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body)
|
||||
end
|
||||
|
||||
# This finalizes the output using the proper HttpResponse way
|
||||
cgi.out {""}
|
||||
rescue Errno::EPIPE
|
||||
# ignored
|
||||
rescue Object => rails_error
|
||||
STDERR.puts "Error calling Dispatcher.dispatch #{rails_error.inspect}"
|
||||
STDERR.puts rails_error.backtrace.join("\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Does the internal reload for Rails. It might work for most cases, but
|
||||
# sometimes you get exceptions. In that case just do a real restart.
|
||||
def reload!
|
||||
@guard.synchronize do
|
||||
$".replace $orig_dollar_quote
|
||||
GC.start
|
||||
Dispatcher.reset_application!
|
||||
ActionController::Routing::Routes.reload
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Creates Rails specific configuration options for people to use
|
||||
# instead of the base Configurator.
|
||||
class RailsConfigurator < Mongrel::Configurator
|
||||
|
@ -86,91 +172,6 @@ module Mongrel
|
|||
log "WARNING: Rails does not support signals on Win32."
|
||||
end
|
||||
end
|
||||
|
||||
# Implements a handler that can run Rails and serve files out of the
|
||||
# Rails application's public directory. This lets you run your Rails
|
||||
# application with Mongrel during development and testing, then use it
|
||||
# also in production behind a server that's better at serving the
|
||||
# static files.
|
||||
#
|
||||
# The RailsHandler takes a mime_map parameter which is a simple suffix=mimetype
|
||||
# mapping that it should add to the list of valid mime types.
|
||||
#
|
||||
# It also supports page caching directly and will try to resolve a request
|
||||
# in the following order:
|
||||
#
|
||||
# * If the requested exact PATH_INFO exists as a file then serve it.
|
||||
# * If it exists at PATH_INFO+".html" exists then serve that.
|
||||
# * Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispath to have Rails go.
|
||||
#
|
||||
# This means that if you are using page caching it will actually work with Mongrel
|
||||
# and you should see a decent speed boost (but not as fast as if you use lighttpd).
|
||||
#
|
||||
# An additional feature you can use is
|
||||
class RailsHandler < Mongrel::HttpHandler
|
||||
attr_reader :files
|
||||
attr_reader :guard
|
||||
|
||||
def initialize(dir, mime_map = {})
|
||||
@files = Mongrel::DirHandler.new(dir,false)
|
||||
@guard = Mutex.new
|
||||
|
||||
# register the requested mime types
|
||||
mime_map.each {|k,v| Mongrel::DirHandler::add_mime_type(k,v) }
|
||||
end
|
||||
|
||||
# Attempts to resolve the request as follows:
|
||||
#
|
||||
#
|
||||
# * If the requested exact PATH_INFO exists as a file then serve it.
|
||||
# * If it exists at PATH_INFO+".html" exists then serve that.
|
||||
# * Finally, construct a Mongrel::CGIWrapper and run Dispatcher.dispath to have Rails go.
|
||||
def process(request, response)
|
||||
return if response.socket.closed?
|
||||
|
||||
path_info = request.params[Mongrel::Const::PATH_INFO]
|
||||
page_cached = request.params[Mongrel::Const::PATH_INFO] + ".html"
|
||||
|
||||
if @files.can_serve(path_info)
|
||||
# File exists as-is so serve it up
|
||||
@files.process(request,response)
|
||||
elsif @files.can_serve(page_cached)
|
||||
# possible cached page, serve it up
|
||||
request.params[Mongrel::Const::PATH_INFO] = page_cached
|
||||
@files.process(request,response)
|
||||
else
|
||||
begin
|
||||
cgi = Mongrel::CGIWrapper.new(request, response)
|
||||
cgi.handler = self
|
||||
|
||||
@guard.synchronize do
|
||||
# Rails is not thread safe so must be run entirely within synchronize
|
||||
Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response.body)
|
||||
end
|
||||
|
||||
# This finalizes the output using the proper HttpResponse way
|
||||
cgi.out {""}
|
||||
rescue Errno::EPIPE
|
||||
# ignored
|
||||
rescue Object => rails_error
|
||||
log "Error calling Dispatcher.dispatch #{rails_error.inspect}"
|
||||
log rails_error.backtrace.join("\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Does the internal reload for Rails. It might work for most cases, but
|
||||
# sometimes you get exceptions. In that case just do a real restart.
|
||||
def reload!
|
||||
@guard.synchronize do
|
||||
$".replace $orig_dollar_quote
|
||||
GC.start
|
||||
Dispatcher.reset_application!
|
||||
ActionController::Routing::Routes.reload
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue