-
Notifications
You must be signed in to change notification settings - Fork 82
Description
Summary
Add support for passing an AbortSignal to the go() query options, enabling cancellation of in-flight DynamoDB operations.
Motivation
Long-running operations like paginated queries, bulk operations, and scans can be resource-intensive and may need to be cancelled in scenarios such as:
- Request timeouts in serverless functions (Lambda, etc.)
- User-initiated cancellation in UI applications
- Circuit breaker patterns in microservices
Currently, once a query is initiated, there's no way to cancel it mid-execution. This feature provides a standard, idiomatic way to handle cancellation using the web-standard AbortController/AbortSignal API.
Proposed API
const controller = new AbortController();
// Pass abortSignal to go() options
const result = await entity.query
.record({ prop1: "value" })
.go({ abortSignal: controller.signal });
// Cancel the operation at any time
controller.abort();Supported Operations
The abortSignal option should work with all ElectroDB operations:
Expected Behavior
-
Pre-aborted signals: If the signal is already aborted when
go()is called, the operation should immediately throw an error without making any DynamoDB requests. -
Mid-execution abort: For operations that involve multiple requests (paginated queries with
pages: "all", bulk operations, hydration), the abort signal should be checked:- Before each page fetch in paginated queries
- Before each batch in bulk get/write operations
- Between the initial query and hydration batch get
-
Error handling: When aborted, operations should throw an
ElectroErrorwith:- Code:
4002 - Error name:
OperationAborted - Message:
"The operation was aborted"
- Code:
Usage Examples
Timeout Pattern
// Abort after 5 seconds
const result = await entity.query
.record({ prop1: "value" })
.go({
abortSignal: AbortSignal.timeout(5000),
pages: "all"
});Manual Cancellation
const controller = new AbortController();
// Start long-running scan
const scanPromise = entity.scan.go({
abortSignal: controller.signal,
pages: "all"
});
// Cancel after some condition
someEventEmitter.on('cancel', () => controller.abort());
try {
const result = await scanPromise;
} catch (err) {
if (err.code === 4002) {
console.log('Operation was cancelled');
}
}AWS SDK Compatibility
This feature should work with both AWS SDK versions:
- v2: Uses the
request.abort()method on the AWS.Request object - v3: Passes the
abortSignaldirectly to theclient.send()options
TypeScript Support
The abortSignal option should be typed in QueryOptions and related interfaces:
interface QueryOptions {
// ... existing options
abortSignal?: AbortSignal;
}