Module: Pgbus::Web::Streamer::IoWriter
- Defined in:
- lib/pgbus/web/streamer/io_writer.rb
Overview
Non-blocking IO writer with a per-call deadline, serialised through the connection’s own mutex. This is the bug-fix for puma/puma#576: a naive ‘io.write(bytes)` on a dead or slow SSE client deadlocks the dispatcher thread until the OS closes the socket (which can take minutes under a TCP keepalive). The message_bus gem hit this in production; we copy the pattern.
The write loop uses write_nonblock + IO.select so a slow client at most stalls *its own* mutex-protected write for ‘deadline_ms`, never the dispatcher or heartbeat thread. When the deadline expires with bytes still pending, we return :blocked; the caller (Connection#enqueue or Connection#write_comment) translates that into mark_dead!, and the heartbeat sweep eventually unregisters the connection.
Returns:
:ok — all bytes written
:closed — peer gone (EPIPE / ECONNRESET / IOError on closed IO)
:blocked — deadline hit before all bytes could be written
Class Method Summary collapse
Class Method Details
.write(connection, bytes, deadline_ms:) ⇒ Object
25 26 27 28 29 |
# File 'lib/pgbus/web/streamer/io_writer.rb', line 25 def self.write(connection, bytes, deadline_ms:) connection.mutex.synchronize do write_all(connection.io, bytes, deadline_ms) end end |