Repository navigation
Conversation
|
No actionable comments were generated in the recent review.
|
A phone that sleeps with an agent session open can wake to a Soup GraphQL websocket the network dropped without a close frame. The socket still reads as open, so graphql-ws never reconnects it: the session's log subscription hears nothing, and the reconnect that makes a session refetch its log never fires. The session stays on the transcript it had when the phone went to sleep. When the app returns to the foreground or comes back online, ping the connected socket and terminate it if the server does not answer within five seconds. graphql-ws reports a terminated socket as close 4499, which is now retried, so it reconnects and every follower refetches what it missed. Each check records its outcome on a graphql_soup.websocket.liveness_check span.
3cc83cc to
ab645f2
Compare
Why
An agent session left open on a phone overnight showed none of the night's messages when the app was opened in the morning.
Macro tasks:
https://macro.com/app/task/01a1884f-0fbf-7350-abf8-b3b907a5a38d
An open session follows its log over the Soup GraphQL websocket and refetches the log whenever that socket reconnects (
subscribeGraphqlSoupReconnected). While the phone sleeps, the network can drop the connection without a close frame. On wake the socket still reads as open, and the client had no keepAlive, so graphql-ws never noticed it was dead. The subscription heard nothing, no reconnect happened, and the session never refetched. A session opened fresh was not affected, because its log query goes over HTTP.How it works
What
createGraphqlSoupWebSocketLiveness(graphql-soup-websocket.ts): while a socket is connected, a return to the foreground or back online sends a protocol ping. If the server does not answer within five seconds, the client callsterminate(). Each check records its outcome (answered/terminated/closed) on agraphql_soup.websocket.liveness_checkspan.createGraphqlSoupWebSocketClient(graphql-soup.ts) wires the check into the client'sconnected/pong/closedevents.graphql-ws-recovery.test.ts): the real graphql-ws client runs over the fake native socket. A silent server is reconnected on resume and the subscription keeps delivering; a server that answers keeps its socket. The first case fails without the check.apps/web/AGENTS.mdnotes the behavior.