Repository navigation
Delivery durability for runs that aren’t served over HTTP or WebSocket #1922
Dan6erbond
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
StreamDurabilityis great, but right now the only way to drive it is through a transport helper (toServerSentEventsResponse,toHttpResponse, the WebSocket helpers). The function that does the work, durableStreamSource instream-to-response.ts, isn’t exported. It batches chunks, appends before forwarding, flushes early at tool calls and terminal events, and callsclose()on every producer exit.That leaves out runs whose producer never returns a response. In our case,
chat()runs inside a Convex action. The action writes the run’s chunks to a database table, and every client (the sender, a second tab, a colleague viewing the same chat) follows the run through a reactive query on that table. There’s no HTTP response to attach durability to, so we ended up writing our own copy ofdurableStreamSource: a buffer, a flush timer, ordered appends and a terminal close. The same applies to queue workers, cron jobs, or any background run that clients join from a database or pub/sub instead of a response stream.We can use the durability log without the transport by exporting the producer side, something like:
pipeToDurabilitycould just be a thin wrapper arounddurableStreamSourcethat drains the source. ExportingdurableStreamSourceitself (plusRUN_ACCEPTED_EVENT) would work just as well.That way the batching, the early flush and the close-on-every-exit guarantee stay in one place, instead of every non-HTTP runtime re-implementing them and getting the edge cases slightly wrong. For example, a terminal batch can get skipped when persistence throws after the stream ends; we hit exactly that.
All reactions