Я работаю над созданием промежуточного программного обеспечения Rack, которое подписывается на канал Redis и отправляет сообщения клиентам с помощью событий, отправленных сервером. Sinatra предоставляет хороший DSL для этого. Однако у меня есть рабочий пример, проблема, с которой я сталкиваюсь, заключается в том, что производительность существенно снижается, когда я добираюсь до 7 или 8 клиентов. Я также столкнулся с проблемами с «мертвой блокировкой» сервера при попытке повторного использования соединения Redis между запросами.
Я использую Thin для обслуживания приложения (которое использует EventMachine под капотом). Я думал, что Sinatra DSL уже поддерживает параллелизм с EventMachine, но, может быть, это то, что мне нужно реализовать самому? Я не хочу ограничиваться только серверами на базе EventMachine (Thin, Rainbows!), если кто-то захочет использовать многопоточный сервер, такой как Puma. Что мне нужно сделать, чтобы увеличить параллелизм в моем коде?
require 'redis'
require 'sinatra/base'
class SSE < Sinatra::Base
def send_message(json)
"id: #{Time.now}\n" +
"data: #{json}" +
"\r\n\n"
end
get '/channels/:id/subscribe', provides: 'text/event-stream' do
channel_id = params['id']
stream(:keep_open) do |connection|
Redis.new.subscribe("channels:#{channel_id}") do |on|
on.message do |channel, json|
connection << send_message(json)
end
end
end
end
end