Ruby Rack: запуск и демонтаж (подключение к Tokyo Cabinet) - PullRequest
3 голосов
/ 06 апреля 2010

Я построил довольно простой REST-сервис в Синатре, на Стойке. Он поддерживается 3 хранилищами данных Tokyo Cabinet / Table, в которых есть соединения, которые нужно открывать и закрывать. У меня есть два класса моделей, написанных на прямом Ruby, которые в настоящее время просто подключаются, получают или кладут то, что им нужно, а затем отключаются. Очевидно, это не сработает в долгосрочной перспективе.

У меня также есть некоторое промежуточное программное обеспечение Rack, например Warden, которое использует эти классы моделей.

Как лучше всего управлять открытием и закрытием соединений? Насколько мне известно, в стойке нет хуков запуска / выключения. Я думал о вставке части промежуточного программного обеспечения, которая предоставляет ссылку на объект TC / TT в env, но тогда мне пришлось бы передать это через Sinatra моделям, что тоже не кажется эффективным; и это будет только подключение к TC по запросу. Я полагаю, что жизненный цикл для каждого экземпляра сервера будет более подходящим сроком службы.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 06 апреля 2010

Рассматривали ли вы использование блоков configure Синатры для настройки ваших соединений?

configure do
  Connection.initialize_for_development
end

configure :production do
  Connection.initialize_for_production
end

Это довольно распространенная идиома при использовании таких вещей, как DataMapper с Sinatra

Ознакомьтесь с разделом «Конфигурация» на http://www.sinatrarb.com/intro

2 голосов
/ 06 апреля 2010

Если у вас есть другое промежуточное программное обеспечение Rack, которое зависит от этих подключений (в зависимости от классов вашей модели), то я бы не стал вводить логику подключения в Sinatra - что произойдет, если вы удалите Sinatra и вставите другое конечная точка?

Поскольку вы хотите подключение-на-приложение, а не-подключение-на-запрос, вы можете легко написать промежуточное программное обеспечение, которое инициализирует и очищает подключения (своего рода Guard Idiom применительно к Rack) и установить это впереди любого другого промежуточного программного обеспечения, которому нужны соединения.

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, поскольку другой поток / запрос мог его закрыть.

...