【问题标题】:Reloading Sinatra app on every request on Windows在 Windows 上的每个请求上重新加载 Sinatra 应用程序
【发布时间】:2010-12-27 15:20:11
【问题描述】:

我已经根据这个thread设置了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 运行精简,但它只重新加载新添加的路由。当我更改已经存在的路线时,它仍然运行旧代码。

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

例如,如果我将路线更改为

get '/' do
  'bar'
end

get '/foo' do
  'baz'
end

/ 仍然会为foo 提供服务,即使它已更改,但/foo 会正确重新加载并为baz 提供服务。

这是正常行为,还是我遗漏了什么?我希望重新加载整个源文件。我现在能想到的唯一方法是在文件系统更改时重新启动整个网络服务器。

我在 Windows Vista x64 上运行,因此我无法使用 shotgun,因为 fork()

【问题讨论】:

    标签: ruby sinatra rack reloading


    【解决方案1】:

    你可以试试sinatra-reloader,众所周知,它在 Windows 上运行良好(而且,它比 shotgun 更快)。

    【讨论】:

    • 我们自己也遇到了这个问题,因为我的团队中有两个使用 Windows,两个使用 Mac。这是我们采用的解决方案,目前看来运行良好。
    • 不仅速度更快,而且我发现 sinatra-reloader 更易于使用 :-)
    【解决方案2】:

    这行得通:

    # 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) 并包含 Sinatra::Application.reset!在应用程序类 (app.rb) 中。
    【解决方案3】:

    Shotgun 不能在 Windows 上运行吗?

    来自自述文件:

                                    Shotgun
    

    这是 rackup 命令的自动重新加载版本 架子。它可以用作提供的复杂重新加载逻辑的替代方案 通过 web 框架或在不支持应用程序重新加载的环境中。

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

    【讨论】:

    • 抱歉,没有看到您关于 Shotgun 的注释
    【解决方案4】:

    您也可以尝试使用Trinidad 一个基于Tomcat 的JRuby Rack 容器。根据我的经验,默认情况下它确实会更改重新加载,而无需修改源文件。也太快了吧如果您使用原生库显然不好,但如果您在 Windows 上部署,您可能习惯于采用纯 ruby​​ 方法。

    它的语法和瘦方法一样简单:

    jruby -S trinidad -r config.ru
    

    没有 Java 特定的牦牛剃须(即创建 web.xml 或对 Ruby 应用程序进行 WARing),并且 gem 易于安装。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 2018-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多