You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A handler cannot ask whether the client is still there #175
HttpResponse::sendable() is the only predicate a streaming handler has, and it answers four questions at once: the response is closed, or sealed by sendFile(), or has no stream ops, or the per-stream queue is full. Three of those are permanent and one is transient, so a caller cannot tell "yield and continue" from "stop".
isClosed() does not fill the gap — it reports that this code called end(), not that the peer left.
The consequence is in the field twice. Our own SSE example carried if (!$response->sendable()) break; // peer gone — stop early until #174; laravel-spawn wrapped the same call as Sse::connected() with the same wording; and YanGusik/laravel-spawn#60 truncated a proxied body at ~100 KB with that loop, under a declared Content-Length, which HTTP/2 then rejected.
Proposal
HttpResponse::isWritable(): bool — output is still possible: end() was not called, the response is not sealed by sendFile(), and the stream was not killed by the peer. Every input is a one-way latch, so a false answer stays false and the predicate is sound, unlike queue depth.
Backed by a new optional is_alive op in http_response_stream_ops_t (include/php_http_server.h:706). No backend needs new state: H2 has stream->peer_closed, the worker path has stream_credit_is_dead, H1 has the connection check h1_stream_append_chunk already makes, H3 the equivalent. A NULL slot answers from the response alone.
Part of the response body contract recorded in dev/PLAN.md.
Activity
docs(changelog): record isWritable() (#175)
Merge pull request #176 from true-async/175-is-writable