Make request deadline extensions reach the socket behind the logging middleware
Long agent turns were cut at exactly 30s on the live instance with "The connection dropped partway through." — the #78 failure, which its tests said was fixed. The tests host openEventStream on a bare gin.New(); in production, slog-gin replaces c.Writer with a wrapper that embeds the gin.ResponseWriter interface, which has no Unwrap, so the ResponseController built from the handler's writer can't reach the connection and every SetWriteDeadline returns ErrNotSupported. The stream fell back to the server's absolute WriteTimeout; the first write past it failed, cancelled the request context, and closed the socket under the client mid-frame. The scan upload's read/write extensions failed the same way, with the errors discarded. captureController now runs first on the engine and stashes a controller built before anything wraps the writer; openEventStream and scanSeedPacket take it from responseController(c). The regression tests run the stream through New() — the real stack, in the real order — and check from the client side; the scan path logs once instead of swallowing the error. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
@@ -160,6 +160,16 @@ Conventions that follow from it:
|
||||
plantings. Fixing it per-call-site is how it came back, which is why the rule
|
||||
lives in `commitScope` where no caller can forget it.
|
||||
|
||||
- **Request deadlines are extended through `responseController(c)`, never
|
||||
`http.NewResponseController(c.Writer)`.** The logging middleware wraps the
|
||||
writer in a type with no `Unwrap`, so a controller built from a handler's
|
||||
writer can't reach the socket: every `SetWriteDeadline`/`SetReadDeadline`
|
||||
returns `ErrNotSupported` — in production only. `captureController` is the
|
||||
first middleware in `api.New` precisely so the controller exists before
|
||||
anything wraps the writer. Corollary for tests: a deadline test must run
|
||||
through `New()`, not `gin.New()` — the #78 fix shipped fully tested on a bare
|
||||
engine and never worked on the live instance.
|
||||
|
||||
## Testing
|
||||
|
||||
Match the test to the failure it would catch:
|
||||
|
||||
Reference in New Issue
Block a user