2011-11-26 55 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

相關問題