docs(quic): SendAsync holds no thread; BytesInFlight and SendsInFlight
The README's QUIC section shows sending without a thread: what onSent's true and false mean, the thread it runs on and what that forbids, and BytesInFlight as the way to drop a follower that cannot keep up. The consumer notes give the full contract, take SendAsync out of the list of what goes through the pool (but for a send msquic never took) and into what runs on msquic's workers; the agent notes count the new test and add onSent to the callbacks that really do run on the worker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
44706f29e7
commit
328561fa91
3 changed files with 19 additions and 6 deletions
13
README.md
13
README.md
|
|
@ -123,6 +123,18 @@ Keep the callback short: it runs on the msquic worker, so no `*Sync` call and no
|
|||
|
||||
`~ClientQUIC` waits, up to 1 s and about a round trip when the peer is there, for its close to reach the peer, so a server learns of a client that went away at once rather than at its idle timeout.
|
||||
|
||||
#### Sending without a thread
|
||||
|
||||
`QUICStream::SendAsync` copies the buffer, hands it to msquic and returns; nothing waits for msquic to take it. Its callback fires exactly once, on msquic's worker thread when msquic is done with the copy: `true` once msquic has taken the whole buffer, `false` when the stream or the connection closed first. Sends queue in call order, from any thread and from inside callbacks, and `BytesInFlight()` / `SendsInFlight()` say how far behind a slow peer is:
|
||||
|
||||
```cpp
|
||||
stream.SendAsync(line.data(), static_cast<std::uint32_t>(line.size()), /*finish=*/false,
|
||||
[](bool sent) { if (!sent) { /* the peer is gone */ } });
|
||||
if (stream.BytesInFlight() > 4 * 1024 * 1024) stream.Stop(); // a follower that cannot keep up
|
||||
```
|
||||
|
||||
The callback runs on msquic's worker, so it must not block (no `*Sync` call) or throw. A send that fails before msquic takes it, on a closed stream for one, reports from a pool task instead, never from inside `SendAsync`. Sends made before the wrapper is destroyed still go out and report. `SendSync` is the blocking form, and throws only when its own send was canceled.
|
||||
|
||||
### HTTP/3 Components
|
||||
|
||||
HTTP/3 runs over QUIC, which always requires TLS. Pass server credentials when constructing the listener (or set `selfSigned = true` for a development-only ephemeral cert) and matching client credentials when constructing the client (`insecureNoServerValidation = true` for self-signed servers).
|
||||
|
|
@ -361,6 +373,7 @@ The library includes tests covering:
|
|||
- Closed-connection notices (`ShouldNotifyClosedConnectionQUIC`) — a server deletes each of 100 accepted connections from its `OnClosed` and the process then exits normally; a peer that exits or freezes, a server-side `Stop()`, a callback set after the close and an owner that deletes first each behave as documented
|
||||
- The peer hears a close (`ShouldTellPeerOfCloseQUIC`) — the server side of each of 20 connections learns at once that the client destroyed its `ClientQUIC`, rather than at the idle timeout
|
||||
- `SendSync` under a fast peer (`ShouldReturnFromSendSyncQUIC`) — 2000 sends to a peer that answers and finishes the stream at once all return
|
||||
- Sending without a thread (`ShouldSendWithoutBlockingQUIC`) — a 16 MiB burst of `SendAsync` returns at once and completes in order; a chain of sends from inside callbacks completes with every pool worker parked; a stopped connection, a destroyed wrapper, concurrent senders and a closed stream each report as documented
|
||||
- WebTransport echo (`ShouldEchoWebTransport`) — extended-CONNECT acceptance, draft-02 SETTINGS, bidi data stream framing (`WT_STREAM 0x41` + session-id varint), and byte-for-byte echo
|
||||
- HTTP/1.1 wire format (`ShouldParseHTTP1`) — serialisation, incremental parsing fed one byte at a time, chunked bodies with trailers, pipelining, interim 1xx, HTTP/1.0 and HEAD framing, and the malformed inputs the parser is required to reject
|
||||
- HTTP/1.1 round-trip (`ShouldSendRecieveHTTP1`) — routing, query strings, HEAD, 404 and a throwing handler
|
||||
|
|
|
|||
Loading…
Reference in a new issue