3

I have built a pretty simple REST service in Sinatra, on Rack. It's backed by 3 Tokyo Cabinet/Table datastores, which have connections that need to be opened and closed. I have two model classes written in straight Ruby that currently simply connect, get or put what they need, and then disconnect. Obviously, this isn't going to work long-term.

I also have some Rack middleware like Warden that rely on these model classes.

接続の開閉を管理する最良の方法は何ですか? 私が知っているように、ラックは起動/シャットダウンフックを提供しません。env の TC/TT オブジェクトへの参照を提供するミドルウェアを挿入することを考えましたが、それを Sinatra 経由でモデルにパイプする必要があり、これも効率的ではないようです。そして、それは TC へのリクエストごとの接続になるだけです。サーバーインスタンスごとのライフサイクルがより適切な寿命になると思います。

ありがとう!

4

2 に答える 2

3

シナトラのconfigureブロックを使用して接続をセットアップすることを検討しましたか?

configure do
  Connection.initialize_for_development
end

configure :production do
  Connection.initialize_for_production
end

Sinatra で DataMapper などを使用している場合、これはかなり一般的なイディオムです。

http://www.sinatrarb.com/introの「構成」セクションを確認してください。

于 2010-04-06T14:00:30.810 に答える
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別のスレッド/リクエストによって接続が閉じられた可能性があるため、フック内の接続の状態をさらに確認する必要がある場合があります。

于 2010-04-06T14:20:53.120 に答える