antirez / antirez/ds4

client disconnect mid-generation not detected on clean TCP FIN (Darwin poll bug)

Abierto
#786 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
C
Estrellas
22.3k
Forks
2.1k
Merge medio
1 d 3 h
PR fusionados (30 d)
4

Descripción

### Bug: client disconnect mid-generation is not detected on a clean TCP FIN (Darwin)

ds4 was originally a macOS-first project (Metal backend), so this Darwin-specific
failure in the server's disconnect handling is the most common platform for it.

The disconnect cancel added in e9ded97 polls the client socket every 100ms from
`wait_for_job_or_disconnect` → `client_socket_disconnected()`, but **Darwin's
`poll()` does not report a plain TCP FIN**: no POLLIN, no POLLHUP — the call
returns 0 (no events). A client that closes the connection cleanly mid-generation
is therefore never seen.

#### Impact

- The job keeps decoding into a dead socket until `max_tokens` — on an M5 Max
that is ~12s of GPU time per disconnect, wasted.
- Only an RST trips cancellation (e.g. `close()` with unread receive data, or a
send failure), and that path returns silently: the `job_cancelled` early
returns in `generate_job_inner` skip the response path where the
"client disconnected" log lives, so cancelled work is invisible in the log.

#### Why the existing test misses it

`test_waiting_job_cancels_on_client_close` uses a socketpair and writes
pipelined data before closing. That makes `poll()` report POLLIN; `recv()` then
hits EOF, so the test passes — a clean FIN with no trailing data never
produces that event on Darwin.

#### Repro

Start the server, send a streaming request with `max_tokens=512`, close the
connection with `shutdown(SHUT_WR)` after a few SSE chunks (no RST). The log
shows all 512 tokens generated (`finish=length`) and never a
"client disconnected" line. Same for non-streaming requests closed
mid-generation.

#### Fix

PR #785 proposes `recv(MSG_PEEK)` probing after an eventless poll (reports EOF
exactly on every platform, consumes nothing, race-free with the worker's SSE
writes on the same fd), plus surfacing the cancellation at the seven early-return
sites. Verified live on M5 Max/Metal: detection in ~0.5s, job stops at
prefill/early decode, server stays healthy.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.