#ruby #asynchronous #redis #eventmachine
#ruby #асинхронный #redis #eventmachine
Вопрос:
Я пытаюсь прочитать URL-адреса из хранилища Redis и просто получить HTTP-статус URL-адресов. Все в EventMachine. Я не знаю, что не так с моим кодом, но он не асинхронный, как ожидалось.
Все запросы выполняются от первого до последнего, и, что любопытно, я получаю только первый ответ (HTTP-заголовок, который я хочу проверить) после последнего запроса. У кого-нибудь есть подсказка, что там происходит не так?
require 'eventmachine'
require 'em-hiredis'
require 'em-http'
EM.run do
@redis = EM::Hiredis.connect
@redis.errback do |code|
puts "Error code: #{code}"
end
@redis.keys("domain:*") do |domains|
domains.each do |domain|
if domain
http = EM::HttpRequest.new("http://www.#{domain}", :connect_timeout => 1).get
http.callback do
puts http.response_header.http_status
end
else
EM.stop
end
end
end
end
Я запускаю этот скрипт для нескольких тысяч доменов, поэтому я ожидаю получить первые ответы перед отправкой последнего запроса.
Комментарии:
1. Это из-за итерации массива ключей по .each? Как выполнить итерацию по нему способом eventmachine?
Ответ №1:
Хотя EventMachine является асинхронным, сам реактор является однопоточным. Итак, пока ваш цикл выполняется и запускает эти тысячи запросов, ни один из них не выполняется до завершения цикла. Затем, если вы вызовете EM.stop , вы остановите реактор перед их выполнением.
Вы можете использовать что-то вроде EM::iterator, чтобы разбить обработку доменов на куски, которые позволяют реактору выполняться. Затем вам нужно будет немного поколдовать, если вы действительно хотите EM.stop, сохранив счетчик отправленных запросов и полученных ответов, прежде чем остановить реактор.
Комментарии:
1. Привет, dj2, большое спасибо за ваше четкое объяснение. Мне не хватает хороших документов, чтобы понять все факты о НИХ. Много нового для изучения 😉