В одном контроллере простого приложения Rails 5 у меня есть 2 действия (live
и test
), оба с использованием ActionController::Live
. live
проходит через цикл и записывает случайные данные в response.stream.write
без каких-либо проблем. Это работает.
В test
однако я использую Redis.subscribe. Вот код действия:
def test
response.headers['Content-Type'] = 'text/event-stream'
redis = Redis.new
redis.subscribe_with_timeout(30, "abc") do |on|
on.message do |event, data|
puts data
response.stream.write data
end
end
rescue IOError
# ignore
ensure
redis.quit
response.stream.close
end
Метод test
, однако, не работает должным образом. Вот что происходит:
Я запускаю приложение и поражаю конечную точку test
с помощью curl
. Скручивание перестает ждать данных, как ожидалось.
Затем в redis-cli
я отправляю сообщение на канал abc
. Сразу же я вижу свое сообщение в окне приложения rails (puts data
) и вижу его в curl:
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
X-Request-Id: 25df052d-e3f2-4327-9a97-088e702460fa
X-Runtime: 2.709001
Transfer-Encoding: chunked
Но хотя все последующие сообщения от redis-cli
печатаются на стороне рельсов, они не принимаются curl до истечения времени ожидания (30 секунд в subscribe_with_timeout
).
Я работаю в Puma, посмотрел и реализовал все ответы Stackoverflow, касающиеся параллелизма, потоков сердцебиения и прочего, но безуспешно.