Skip to content

read-api: pass request.signal into Sheet.query/queryFirst/queryAll for client-disconnect cancellation #34

@themightychris

Description

@themightychris

gitsheets 1.0.5 shipped AbortSignal support on Sheet.query / queryFirst / queryAll (upstream #154). plans/read-api.md shipped before this was available, so our read services don't currently honor cancellation.

What

Thread request.signal (Fastify provides one when the client disconnects) into the Sheet.query calls in apps/api/src/services/* so a slow query for a disconnected client aborts at the next yield boundary instead of running to completion.

Why

At civic scale we won't hit it often, but a ?q=… over a large in-memory corpus could chew CPU after the user has navigated away. Free win for ~5 lines.

How

Each service method needs an AbortSignal parameter threaded from the route:

fastify.get('/api/projects', async (request) => {
  return projectService.list({ ...query, signal: request.raw.signal });
});
async list(opts: { signal?: AbortSignal, ...}) {
  for await (const project of this.sheet.query({ signal: opts.signal })) {
    // ...
  }
}

Tests: a unit test that aborts mid-iteration and asserts the AbortError reason matches.

Out of scope

  • The FTS engine's ?q=… path (better-sqlite3) doesn't expose an AbortSignal hook in its own API; cancellation there waits on a separate decision.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions