From harness-claude
Implements timeouts for HTTP requests, DB queries, and async ops using AbortController, AbortSignal.timeout(), and deadline propagation to prevent hangs and exhaustion.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Prevent resource exhaustion and hung requests with timeouts, AbortController, and deadline propagation
Generates PHP 8.4 timeout pattern components for execution limits in API calls, DB queries, queues, file ops; includes signal/stream executors, PSR-15 middleware, fallbacks, tests.
Provides step-by-step guidance, production-ready code, and configurations for timeout handlers in API integrations with third-party APIs, webhooks, SDKs, and OAuth.
Provides expertise in async patterns for Python asyncio, JS/TS promises, C# async/await, Rust futures. Covers concurrency, event loops, error handling, backpressure, cancellation, optimization.
Share bugs, ideas, or general feedback.
Prevent resource exhaustion and hung requests with timeouts, AbortController, and deadline propagation
AbortController with AbortSignal.timeout() for fetch requests.// utils/timeout.ts
export async function withTimeout<T>(
fn: (signal: AbortSignal) => Promise<T>,
timeoutMs: number,
errorMessage = 'Operation timed out'
): Promise<T> {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
try {
const result = await fn(controller.signal);
return result;
} catch (error) {
if (controller.signal.aborted) {
throw new TimeoutError(errorMessage, timeoutMs);
}
throw error;
} finally {
clearTimeout(timeoutId);
}
}
export class TimeoutError extends Error {
constructor(
message: string,
public readonly timeoutMs: number
) {
super(message);
this.name = 'TimeoutError';
}
}
// Usage with fetch
import { withTimeout } from './utils/timeout';
const user = await withTimeout(
(signal) => fetch('/api/users/123', { signal }).then((r) => r.json()),
5000,
'User fetch timed out'
);
// Node.js built-in (Node 18+)
const response = await fetch('/api/data', {
signal: AbortSignal.timeout(5000),
});
// Deadline propagation across services
async function handleRequest(req: Request) {
const deadline = Date.now() + 10000; // 10s total budget
const user = await withTimeout(
(signal) => userService.getUser(req.userId, signal),
3000 // 3s budget for user service
);
const remaining = deadline - Date.now();
if (remaining <= 0) throw new TimeoutError('Request deadline exceeded', 10000);
const orders = await withTimeout(
(signal) => orderService.getOrders(user.id, signal),
Math.min(remaining, 5000) // Remaining budget, capped at 5s
);
return { user, orders };
}
AbortController in Node.js: Supported natively since Node 16. AbortSignal.timeout(ms) is available since Node 18 — it creates a signal that automatically aborts after the specified time.
Timeout layering: Set timeouts at multiple levels:
fetch signal, Axios timeout configwithTimeout wrapperCommon timeout values:
Database timeouts:
// PostgreSQL via node-postgres
const pool = new Pool({
connectionTimeoutMillis: 5000, // Wait for connection
query_timeout: 10000, // Query execution limit
statement_timeout: 10000, // Server-side timeout
});
Anti-patterns:
https://nodejs.org/api/globals.html#class-abortcontroller