Skip to content

Add a query timeout #19

Closed
Closed

Description

@prrao87

Problem

A query can't be given a time limit. execute() blocks until the query finishes. The only way to stop it is Ctrl-C: block_on() releases the GIL and checks for signals every 100 ms, cancelling the query on KeyboardInterrupt. A service or a benchmark harness can't rely on that, so a query with an unexpectedly large intermediate result (see #11) runs until it finishes or the process is killed.

Evidence

Every other engine in both benchmark repositories enforces a 10-second limit per query (Neo4j's transaction timeout, Kuzu's and Ladybug's set_query_timeout, DuckDB's interrupt(), FalkorDB's per-query timeout). lance-csr is the only one that runs without a limit, which both repositories' READMEs have to note.

Suggested fix

Add a timeout argument (seconds, default none) to CypherEngine.execute(), execute_batches() and CypherQuery.execute(), enforced as a third branch of the existing tokio::select! in block_on()'s result_or_interrupt(): when the deadline passes, the query future is dropped, which cancels its tasks, and TimeoutError is raised. execute_batches() needs the deadline applied to each batch read. Check that long-running custom operators (CSR expansion, shortest path) yield to the runtime often enough to be cancelled promptly.

Acceptance criteria

  • A query that exceeds timeout raises TimeoutError within a small margin, and its tasks stop (no background CPU afterwards).
  • The engine stays usable after a timeout; a test runs a query after one.
  • docs/api-reference.md and the relevant guide document the argument.
  • The benchmark runners set it, so lance-csr follows the same rules as the other engines.

Identified from the benchmark setup; not prototyped.

Activity

  1. prrao87 commented on Oct 27, 2026

    @prrao87
    MemberAuthor

    Addressed on main by #55. CypherQuery.execute(), CypherEngine.execute() and CypherEngine.execute_batches() take a keyword-only timeout in seconds and raise TimeoutError (streaming readers check the deadline between reads). It's documented in docs/api-reference.md, and with_execution_deadline is the Rust equivalent. The benchmark runners in the external benchmark repositories still need to pass timeout; that work lives in those repositories.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions