Skip to content

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

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
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions