如果你有其他依赖于这些连接的 Rack 中间件(通过依赖于你的模型类),那么我不会把连接逻辑放在 Sinatra 中——如果你去掉 Sinatra 并放入另一个端点会发生什么?
由于您想要每个应用程序连接而不是每个请求连接,因此您可以轻松编写一个中间件来初始化和清理连接(类似于应用于 Rack 的 Guard Idiom)并在任何其他需要的中间件之前安装它连接。
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
挂钩中的连接状态,因为另一个线程/请求可能已经关闭了它。