Использование EventMachine с Thin
Недавно я перешел с монгрела на тонкий при обновлении до рельсов 3. До перехода мы использовали EventMachine без каких-либо проблем. После переключения на thin при каждом вызове EventMachine сервер будет бомбить и сообщать, что возвращаемая нами переменная равна nil.
Из того, что я понимаю, thin использует EventMachine, что, вероятно, вызывает конфликт с реализацией, которая использовалась с Mongrel. Я не очень много работал с EventMachine, но мне кажется, что мне нужно запустить EventMachine внутри другого экземпляра, чтобы отделить его от EventMachine, который используется thin. Я на правильном пути? Как бы я пошел на мгновение, чтобы это запустить в своем собственном процессе отдельно от Thin's EventMachine?
Вот фрагмент EventMachine, который мы в настоящее время реализовали
def connect
EventMachine.run {
args, options = {
:query => @options[:query],
:head => @options[:headers]
}, {
:connect_timeout => @options[:timeout],
:inactivity_timeout => @options[:timeout]
}
args[:body] = @options[:data] if allow_body?
args[:redirects] = @options[:redirects] if @options[:redirects]
http = EventMachine::HttpRequest.new(@uri, options).send(@options[:method], args)
http.errback {
@response = HttpConnection::Response.new(http, false, @options[:logger])
EventMachine.stop
}
http.callback {
@response = HttpConnection::Response.new(http, true, @options[:logger])
EventMachine.stop
}
}
return @response
end
1 ответ
Thin уже обеспечивает и управляет реактором EventMachine, поэтому вам не нужно устанавливать его отдельно. Я не думаю, что вам нужно встраивать этот код в EventMachine.run {}
блок для начинающих.
Есть несколько проблем с вашим подходом здесь. Во-первых, вернулся @response
переменная всегда будет равна нулю, потому что EventMachine::HttpRequest
происходит асинхронно, и не даст вам никаких данных, пока вы не нажмете http.callback {}
блок. Во-вторых, в каждом из EventMachine::HttpRequest
обратные вызовы, вы звоните EventMachine.stop
, Это будет иметь эффект остановки thin
веб-сервер, вероятно, именно поэтому вы видите взрыв сервера.
Если вы пытаетесь запустить такой код в приложении rails, вам может понадобиться найти способ обрабатывать вызовы асинхронно, чтобы приложение не зависало в ожидании долгого процесса. Хороший подход, который я использовал для этого, состоит в том, чтобы использовать Sinatra, который имеет плагин async, позволяющий вам держать открытые долгосрочные запросы. Затем вы можете включить это в свое приложение rails3, используя rails metal, чтобы запросы к вашему асинхронному коду / Eventmachine отправлялись в sinatra.