私は、Redis チャネルをサブスクライブし、Server Sent Events を使用してメッセージをクライアントにプッシュする Rack ミドルウェアの構築に取り組んでいます。Sinatra は、これを行うための優れた DSL を提供しています。実際の例がありますが、私が直面している問題は、クライアントが 7 または 8 になるとパフォーマンスが大幅に低下することです。リクエスト間でRedis接続を再利用しようとすると、サーバーが「デッドロック」するという問題にも遭遇しました。
私は Thin を使用してアプリを提供しています (内部で EventMachine を使用しています)。Sinatra DSL は既に EventMachine との同時実行を処理していると思いましたが、これは自分で実装する必要があるのでしょうか? 誰かが Puma のようなマルチスレッド サーバーを使用したい場合に備えて、EventMachine ベースのサーバー (Thin、Rainbows!) だけに自分自身を制限したくありません。コードの同時実行性を高めるにはどうすればよいですか?
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