在Windows上每次请求重新加载Sinatra应用程序

8

根据这个帖子,我已经设置好了Rack::Reload

# config.ru
require 'rubygems'
require 'sinatra'

set :environment, :development

require 'app'
run Sinatra::Application

# app.rb  
class Sinatra::Reloader < Rack::Reloader
  def safe_load(file, mtime, stderr = $stderr)
    if file == Sinatra::Application.app_file
      ::Sinatra::Application.reset!
      stderr.puts "#{self.class}: reseting routes"
    end
    super
  end
end

configure(:development) { use Sinatra::Reloader }

get '/' do
  'foo'
end

通过thin start -R config.ru运行thin,但它只会重新加载新添加的路由。当我更改已经存在的路由时,它仍然运行旧代码。

当我添加新路由时,它正确地重新加载它,因此可以访问,但它不会重新加载其他内容。

例如,如果我更改了路由:

get '/' do
  'bar'
end

get '/foo' do
  'baz'
end
/仍然可以提供foo,即使它已经更改,但是/foo将正确重新加载并提供baz。这是正常行为吗?还是我漏掉了什么?我期望整个源文件被重新加载。目前我能想到的唯一解决方法是在文件系统更改时重新启动整个Web服务器。我正在运行Windows Vista x64,因此无法使用fork(),也就无法使用shotgun
4个回答

21
你可以尝试使用 sinatra-reloader,这个工具在Windows上运行良好(而且比shotgun更快)。

1
我们自己也遇到了这个问题,因为我的团队中有两个人使用Windows,另外两个人使用的是Mac。这是我们采用的解决方案,目前看来效果不错。 - Joshua Cheek
2
不仅速度更快,而且我发现sinatra-reloader更容易使用 :-) - Radek

5

这个可以实现:

# config.ru
require 'rubygems'
require 'app'

set :environment, :development
run Sinatra::Application

# app.rb  
require 'sinatra'

class Sinatra::Reloader < Rack::Reloader
  def safe_load(file, mtime, stderr = $stderr)
    if file == File.expand_path(Sinatra::Application.app_file)
      ::Sinatra::Application.reset!
      stderr.puts "#{self.class}: reseting routes"
    end
    super
  end
end

configure(:development) { use Sinatra::Reloader }

get '/' do
  'foo'
end

您所编写的代码中 require 语句的位置非常重要。但是我认为以下方案更加优雅和健壮:

# config.ru
require 'rubygems'
require 'sinatra'
require 'rack/reloader'
require 'app'

set :environment, :development

use Rack::Reloader, 0 if development?
run Sinatra::Application

# app.rb  
Sinatra::Application.reset! 
get '/' do
  'foo'
end

完美!对于一个模块化的应用程序,运行MyAppClassName(config.ru),并在应用程序类(app.rb)中包含Sinatra :: Application.reset! - aaandre

0

Shotgun在Windows上无法工作吗?

从README中可以看到:

                                Shotgun

这是一个自动重新加载版本的rackup命令,它与Rack一起提供。它可以用作复杂重新加载逻辑的替代品,也可以在不支持应用程序重新加载的环境中使用。

shotgun命令启动Rack支持的服务器之一(例如mongrel、thin、webrick),并侦听请求,但不加载实际应用程序的任何部分。每次收到请求时,它会fork一个子进程,在子进程中加载应用程序,处理请求,然后退出子进程。结果是在每个请求上对所有源文件和模板进行干净的应用程序范围内重新加载。


抱歉,我没有看到你关于“Shotgun”的注释。 - Mike H

0

你也可以尝试使用Trinidad,这是一个基于Tomcat的JRuby Rack容器。根据我的经验,它默认情况下会改变重新加载而无需修改源文件。速度非常快。如果你正在使用本地库,那么显然不适用,但如果你在Windows上部署,你可能已经习惯了采用纯Ruby方法。

它的语法与thin方法一样简单:

jruby -S trinidad -r config.ru

没有Java特定的“牦牛剃须”(即创建web.xml或WARing您的Ruby应用程序),而且这个gem很容易安装。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接