Сделайте что-нибудь, когда пользователь прерывает соединение (Sinatra + Thin) - PullRequest
3 голосов
/ 08 декабря 2011

Я пишу приложение, которое иногда требует очень длительных запросов к БД. Я хотел бы выполнить некоторый код, если клиент перезагружает или закрывает страницу, чтобы сделать что-то с запросами БД.

Я надеялся, что у Рэка будут зацепки за эту штуку, но, судя по тому, что я видел, это уровень глубже, чем у Рэка.

Пока что единственный хук, который я могу найти, - это сам тонкий, с помощью монтирования-исправления функции unbind в классе тонкий соединения:

module Thin
  class Connection < EventMachine::Connection

    def unbind

      # DO something here

      @request.async_close.succeed if @request.async_close
      @response.body.fail if @response.body.respond_to?(:fail)
      @backend.connection_finished(self)
    end
  end
end

Это отменяет функцию отмены привязки Thin и позволяет мне подключиться к разъединению, вызываемому EventMachine.

Есть ли лучший способ?

1 Ответ

1 голос
/ 25 декабря 2011

После некоторых копаний я обнаружил, что Thin предоставляет механизм для замены 'backend', или как сервер соединяется с клиентом. Я использую это в сочетании со значениями в стойке env, чтобы иметь дело с конкретными экземплярами запроса и узнать, нужно ли мне убить запрос:

class Backend < Thin::Backends::TcpServer

  def initialize(host, port, options={})
    super(host, port)
  end

  def connection_finished(connection)
    super(connection)

    if connection.request.env["query_killer"]
      connection.request.env["query_killer"].kill
    end

  end

end

Это может быть включено в thin через аргументы командной строки:

thin start  -r 'my_module/backend' --backend MyModule::Backend
...