2011-11-26 54 views
8

当新的http请求进入时,Sinatra的新实例将被启动,例如, sinatra被初始化,还是sinatra的前一个实例(相应的get/post方法/路由)的方法被调用? 谢谢你的任何文档链接,我无法找到任何。Sinatra的新实例是否在每次请求时开始?

这也将是有趣的,如果该行为是依赖于部署类型 - 使用WEBrick /乘客等

+0

我见过很多关于如何强制Sinatra/Rack重新加载源文件和应用程序的讨论,所以我的猜测是,他们没有得到重新加载默认情况下,我的问题是否正确吗? –

+0

知道该行为是否依赖于部署类型也会非常有趣 - WEBrick的行为与Passenger相同吗? –

+0

@Oleg:“重新加载Ruby源文件”和“创建新实例”是不同的概念。前者由'require'或'load'完成,后者是'TheClass.new'。 – miaout17

回答

12

新类是为每个请求创建的。但是,这是由Rack完成的而不是。这是Sinatra的一个特色。如果你想深入细节:实际上并不是用Sinatra::Application.new创建的,而是用Sinatra::Application.prototype.dup创建的,代码见Sinatra::Base#call

+0

因此,当没有处理任何请求时,Rack只是在等待一个加载了“空”的Sinatra实例的请求。然后,当一个请求进入时,Rack告诉这个实例复制并处理请求,我知道了吗? – user562529

+0

实际上它是有意义的,将这个信息添加到sinatra文档站点 –

+5

它实际上是记录:http://www.sinatrarb.com/intro#Request/Instance%20Scope –

0

快速测试表明,相同的实例在运行任何请求(至少,默认情况下)。

require 'sinatra' 

flag = false 

get '/stuff' do 
    puts "flag is #{flag ? 'set' : 'unset'}" 
    flag = true 
end 

当这个代码运行并接收到两个请求,服务器会提示flag is unset然后flag is unset

编辑:

,显示文件不被重新加载。通过使用puts self.object_id, self.class(如推荐的pguardiario),我们实际上看到为每个请求创建了一个新的Sinatra::Application实例。

+1

这不是表明它是不同的实例吗?也许更好的测试是:puts self.object_id – pguardiario

+0

好吧,它表明该文件没有被重载为@Oleg所说的,你是对的:用self.object_id,我们看到这是一个不同的Sinatra :: Application实例为每个请求。我现在编辑我的答案。 – thoferon

+0

再次 - 在ruby testfile2.rb下运行,在第一次调用时标志为未设置,并在所有后续调用中设置标志。随着霰弹枪,你会得到标志总是未设置。所以依靠这种网络服务器的行为是一个坏消息。 –

0

运行它,你就会知道一切,但它也不代表机架的机械运行为西纳特拉的。(实际上,机架会为每个请求创建一个新的实例)

require 'sinatra' 

configure do 
    set :number, 0 
end 

number = 0 

get '/test1' do 
    var = "The number is #{number}" 
    number = number + 1 
    var 
end 

get '/test2' do 
    var = "The number is #{settings.number}" 
    set :number, settings.number + 1 
    var 
end 
+0

以'ruby test file.rb'的形式运行这个文件,并在浏览器中敲击test1的结果是“数字是0”,然后“数字是1”,然后“数字是2” - 然后切换到打击test2和它再次从0开始,然后爬升。 –

+0

使用'shotgun'运行此文件会导致'数字为0' - 总是,无论您做什么。 –

2

您应该始终假设整个应用程序可以在您的请求之间重新启动。如果您正在运行16个应用程序副本 - 来自用户'jane'的'/'的请求可能会在副本#2中存在,那么当她访问'/注册'时,请求将会打到#12(可能会为此启动事件)应用程序。因此,Sinatra所做的并不重要(尽管它看起来像是做了类似的事情),因为你的应用可能会出现在任何地方,从今天,昨天或几分钟前启动。

如果你打算在增长 - 或者依靠Heroku等 - 你的应用需要使用'shotgun'运行良好 - 它会重新启动每个请求的所有内容。我想如果你的应用程序做了一些与服务网页完全不同的事情,并且几乎没有崩溃或重新启动,那么你可能会逃避'NO'

所以我的答案是'是'(但并不总是,有时甚至没有通常情况下)。然而,知道事情如何工作很方便,因此您可能只能为每个应用程序加载设置一次复杂的计算资产缓存方案 - 这是性能选择。例如,如果每次使用url/calculate_pi?decimals = 2000调用您的应用程序总是导致相同的2000位数字,则可以在每个实例上缓存该数字。

+0

也谢谢你的实际答案。我肯定不会一直依靠相同的实例。 “知道事情如何工作很方便” - 这就是我问这个问题的原因。 “所以我的回答是'是'(但并不总是,甚至有时甚至不是)”。对了解“请求周期”的工作原理没有帮助。对不起,我的问题显然写得很糟糕。 – user562529

相关问题