Class: InstantRecord::EventsController
- Inherits:
-
ActionController::Base
- Object
- ActionController::Base
- InstantRecord::EventsController
- Defined in:
- app/controllers/instant_record/events_controller.rb
Defined Under Namespace
Classes: EventStream
Constant Summary collapse
- EVENT_STREAM_HEADERS =
SSE change stream as a lazily-enumerated response body — not ActionController::Live (which burns a thread per stream and bypasses the fiber scheduler). An #each body is the portable Rack streaming interface: Puma and Falcon both write each chunk as it is yielded. Under Falcon each stream is a fiber, so
sleepand pg queries suspend the fiber; under Puma the body holds the request thread.The change-log row id is the event id, which doubles as the client's cursor: catch-up from ?after= (or the Last-Event-ID reconnect header), then tail for a bounded window and close. ?window= lets a client shorten the tail — the gem's own sync loop polls with window=0 (catch-up only) so a tick never holds a long stream.
{ "content-type" => "text/event-stream", "cache-control" => "no-store", "x-accel-buffering" => "no" }.freeze
Instance Method Summary collapse
Instance Method Details
#index ⇒ Object
40 41 42 43 44 45 |
# File 'app/controllers/instant_record/events_controller.rb', line 40 def index cursor = (request.headers["Last-Event-ID"] || params[:after] || 0).to_i headers.merge!(EVENT_STREAM_HEADERS).merge!(InstantRecord::CORS_HEADERS) self.response_body = EventStream.new(cursor: cursor, deadline: Time.current + window_seconds) end |