Ruby机架:启动和拆卸操作(东京机柜连接)

Ruby机架:启动和拆卸操作(东京机柜连接),ruby,connection,sinatra,rack,tokyo-cabinet,Ruby,Connection,Sinatra,Rack,Tokyo Cabinet,我在Sinatra的机架上建立了一个非常简单的REST服务。它由3个Tokyo Cabinet/Table数据存储支持,这些数据存储具有需要打开和关闭的连接。我有两个直接用Ruby编写的模型类,它们目前只需连接、获取或放置所需的内容,然后断开连接。显然,这不会长期奏效 我还有一些机架中间件,比如Warden,它们依赖于这些模型类 管理打开和关闭连接的最佳方法是什么?据我所知,机架不提供启动/关闭挂钩。我曾考虑过在env中插入一个中间件来提供对TC/TT对象的引用,但随后我不得不通过Sinatra

我在Sinatra的机架上建立了一个非常简单的REST服务。它由3个Tokyo Cabinet/Table数据存储支持,这些数据存储具有需要打开和关闭的连接。我有两个直接用Ruby编写的模型类,它们目前只需连接、获取或放置所需的内容,然后断开连接。显然,这不会长期奏效

我还有一些机架中间件,比如Warden,它们依赖于这些模型类

管理打开和关闭连接的最佳方法是什么?据我所知,机架不提供启动/关闭挂钩。我曾考虑过在env中插入一个中间件来提供对TC/TT对象的引用,但随后我不得不通过Sinatra将其传递到模型,这似乎也不太有效;这将只得到一个到TC的按请求连接。我认为每个服务器实例的生命周期将是更合适的生命周期


谢谢

您是否考虑过使用Sinatra的配置块来设置连接

configure do
  Connection.initialize_for_development
end

configure :production do
  Connection.initialize_for_production
end
在Sinatra中使用DataMapper之类的东西时,这是一个非常常见的习惯用法


查看位于

的配置部分,如果您有其他机架中间件通过依赖于模型类的方式依赖于这些连接,那么我不会将连接逻辑放在Sinatra中-如果您删除Sinatra并放入另一个端点会发生什么

因为您希望每个应用程序都有连接,而不是每个请求都有连接,所以您可以轻松编写一个中间件来初始化和清理连接,就像应用于机架的Guard惯用法一样,并在需要连接的任何其他中间件之前安装它

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散列中,但您还需要更改模型。也许这个中间件可以在每个模型类中设置一个连接变量,而不是在内部存储它?在这种情况下,您可能需要在at_exit hook中对连接状态进行更多检查,因为另一个线程/请求可能已将其关闭。

您将赢得奖品。这是几个SO帖子中唯一有效的答案!