#ruby #event-handling
#ruby #обработка событий
Вопрос:
Я использую библиотеку EventMachine от Ruby для асинхронного доступа к внешним API RESTful с сервера Ruby, который я пишу. Один из методов, которые я делаю доступными через мой сервер, требует, чтобы был доступен доступ к нескольким внешним API и агрегированные ответы, прежде чем возвращать ответ клиенту, обращающемуся к моему серверу. Вот как я это делаю сейчас…
def aggregate
responses = Array.new
done = 0
# clients are EM::Deferrable objects...
clients.each do |client|
client.callback do |response|
responses << response
done = 1
end
client.errback do |response|
done = 1
end
end
until done == clients.length
sleep 1
end
return responses
end
Есть ли лучшие способы справиться с ситуацией такого типа? Возможно ли, что класс EM::Completion, поставляемый в версии 1.0.0 EventMachine, обеспечит подключение, которое лучше поддерживает такой вариант использования?
Я уверен, что эта проблема возникала раньше (хотя я не смог найти аналогичный вопрос в StackOverflow), поэтому мне любопытно посмотреть, как другие подошли к проблеме.
Ответ №1:
Прежде всего, использование sleep полностью противоречит назначению EventMachine. Этим вы блокируете цикл событий. Мне нужна большая картина для предложения о том, как сделать это лучше, но ваш код должен привыкнуть к тому факту, что метод возвращается до выполнения всех запросов. В качестве альтернативы посмотрите на em-synchrony, как выполнять событийное программирование в процедурном стиле с использованием волокон Ruby (прозрачно для вас).
Один из способов уменьшить количество склеиваемого кода для параллельного выполнения нескольких запросов — это использовать что-то вроде мультиинтерфейса em-http-requests, который работает как с обратным вызовом EventMachine, так и с em-синхронией.
EM::Завершение, с другой стороны, скорее отсрочено, оно точно не поможет вам в этом случае.
Комментарии:
1. Спасибо roidrage, класс MultiRequest для em-http-request — это именно тот тип, который я искал.