2010-04-06 37 views
3

我在Rack上的Sinatra中構建了一個非常簡單的REST服務。它由3個東京內閣/表數據存儲支持,這些數據存儲具有需要打開和關閉的連接。我有兩個使用直接Ruby編寫的模型類,它們只是簡單地連接,獲取或放置他們需要的東西,然後斷開連接。顯然,這不是長期的工作。Ruby Rack:啓動和拆卸操作(東京Cabinet連接)

我也有一些像Warden這樣依賴這些模型類的Rack中間件。

管理打開和關閉連接的最佳方式是什麼?據我所知,機架不提供啓動/關閉掛鉤。我曾想過插入一段中間件,它提供了env中TC/TT對象的引用,但是我不得不通過Sinatra將這些內容傳遞給模型,這看起來效率也不高。這隻會成爲TC的每個請求連接。我認爲每服務器實例生命週期將是一個更合適的壽命。

謝謝!

回答

2

「配置」一節。如果你有依賴於這些連接(通過方式等Rack中間件退房是一個相當常見的成語依賴於你的模型類),那麼我不會把連接邏輯放在Sinatra中 - 如果你翻譯Sinatra並放入另一個端點會發生什麼?

既然你連接的每個應用程序,而不是連接的每個請求,你可以很容易地編寫初始化和清理連接(排序衛隊成語適用於機架)的中間件,並且提前安裝任何其他需要連接的中間件。

class TokyoCabinetConnectionManagerMiddleware 
    class <<self 
    attr_accessor :connection 
    end 

    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    open_connection_if_necessary! 
    @app.call(env) 
    end 

    protected 

    def open_connection_if_necessary! 
    self.class.connection ||= begin 
     ... initialize the connection .. 
     add_finalizer_hook! 
    end 
    end 

    def add_finalizer_hook! 
    at_exit do 
     begin 
     TokyoCabinetConnectionManagerMiddleware.connection.close! 
     rescue WhateverTokyoCabinetCanRaise => e 
     puts "Error closing Tokyo Cabinet connection. You might have to clean up manually." 
     end 
    end 
    end 
end 

如果以後決定要連接的每線程或連接的每個請求,您可以更改這個中間件放在env Hash的連接,但你需要改變你的模型以及。也許這個中間件可以在每個模型類中設置一個connection變量,而不是在內部存儲它?在這種情況下,您可能需要更多地檢查at_exit鉤子中的連接狀態,因爲另一個線程/請求可能已關閉它。

+0

太棒了。謝謝! – 2010-04-06 19:55:09

3

您是否考慮過使用Sinatra的configure塊來建立連接?

configure do 
    Connection.initialize_for_development 
end 

configure :production do 
    Connection.initialize_for_production 
end 

這樣做雖然使用像DataMapper的與西納特拉

http://www.sinatrarb.com/intro

+0

你先生贏得獎品。這是幾個有效的SO帖子中唯一的答案! – 2016-02-16 01:44:34