【问题标题】:Ruby Rack: startup and teardown operations (Tokyo Cabinet connection)Ruby Rack:启动和拆卸操作(Tokyo Cabinet 连接)
【发布时间】:2010-04-06 05:28:54
【问题描述】:

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

我还有一些 Rack 中间件,例如 Warden,它们依赖于这些模型类。

管理打开和关闭连接的最佳方法是什么?据我所知,Rack 不提供启动/关闭挂钩。我曾考虑在 env 中插入一个提供对 TC/TT 对象的引用的中间件,但随后我必须通过 Sinatra 将其通过管道传递给模型,这似乎也没有效率;这只会是与 TC 的按请求连接。我想 per-server-instance-lifecycle 会是一个更合适的生命周期。

谢谢!

【问题讨论】:

    标签: ruby connection sinatra rack tokyo-cabinet


    【解决方案1】:

    您是否考虑过使用 Sinatra 的 configure 块来建立您的连接?

    configure do
      Connection.initialize_for_development
    end
    
    configure :production do
      Connection.initialize_for_production
    end
    

    在将 DataMapper 与 Sinatra 一起使用时,这是一个很常见的习惯用法

    查看http://www.sinatrarb.com/intro的“配置”部分

    【讨论】:

    • 您先生中奖了。这是几个有效的 SO 帖子中唯一的答案!
    【解决方案2】:

    如果您有其他依赖于这些连接的 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 挂钩中的连接状态,因为另一个线程/请求可能已将其关闭。

    【讨论】:

      猜你喜欢
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-27
      • 1970-01-01
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多