ismael3s-polly
v0.0.1
Published
A JavaScript/TypeScript port of the popular .NET [Polly](https://github.com/App-vNext/Polly) library, built with RxJS and compatible with AsyncLocalStorage for context preservation.
Maintainers
Readme
Polly.js - JavaScript Resilience Library
A JavaScript/TypeScript port of the popular .NET Polly library, built with RxJS and compatible with AsyncLocalStorage for context preservation.
Features
- Timeout Strategy: Automatically timeout operations that take too long
- Retry Strategy: Retry failed operations with configurable delay and exponential backoff
- AsyncLocalStorage Compatibility: Preserve context across async operations
- Fluent Builder API: Intuitive builder pattern similar to .NET Polly
- RxJS Integration: Built on top of RxJS for powerful reactive programming
- TypeScript Support: Full TypeScript support with proper type definitions
Quick Start
import {
ResiliencePipelineBuilder,
TimeoutError,
RetryExhaustedError,
} from "./src/index";
import { AsyncLocalStorage } from "async_hooks";
// Create a simple pipeline with timeout and retry
const pipeline = new ResiliencePipelineBuilder()
.withTimeout(2000) // 2 second timeout
.withRetry(3, 500, 1.5) // 3 retries with exponential backoff
.build();
// Execute a function that might fail
try {
const result = await pipeline.execute(async () => {
// Your potentially unreliable operation
const response = await fetch("https://api.example.com/data");
return await response.json();
});
console.log("Success:", result);
} catch (error) {
if (error instanceof TimeoutError) {
console.log("Operation timed out");
} else if (error instanceof RetryExhaustedError) {
console.log("All retry attempts failed");
}
}Examples
Basic Timeout
const timeoutPipeline = new ResiliencePipelineBuilder()
.withTimeout(1000)
.build();
try {
await timeoutPipeline.execute(async () => {
await new Promise((resolve) => setTimeout(resolve, 2000)); // Will timeout
return "Success";
});
} catch (error) {
console.log(error.message); // "Operation timed out after 1000ms"
}Retry with Exponential Backoff
const retryPipeline = new ResiliencePipelineBuilder()
.withRetry(3, 100, 2) // 3 retries: 100ms, 200ms, 400ms delays
.build();
let attempts = 0;
try {
const result = await retryPipeline.execute(async () => {
attempts++;
if (attempts < 3) {
throw new Error(`Attempt ${attempts} failed`);
}
return `Success on attempt ${attempts}`;
});
console.log(result); // "Success on attempt 3"
} catch (error) {
console.log("All retries exhausted");
}Strategy Composition
Strategies are applied in the order they are added to the builder:
- Timeout → Retry: Timeout applies to each retry attempt
- Retry → Timeout: Timeout applies to the entire retry sequence
Choose the order based on your requirements:
// Timeout per retry attempt (recommended for most cases)
const pipeline1 = new ResiliencePipelineBuilder()
.withTimeout(1000) // Each attempt times out after 1s
.withRetry(3) // Up to 3 attempts
.build();
// Timeout for entire operation
const pipeline2 = new ResiliencePipelineBuilder()
.withRetry(3) // Up to 3 attempts
.withTimeout(5000) // Entire operation times out after 5s
.build();TypeScript Support
This library is written in TypeScript and provides full type safety:
interface ApiResponse {
id: number;
name: string;
}
const result: ApiResponse = await pipeline.execute(
async (): Promise<ApiResponse> => {
const response = await fetch("/api/user");
return await response.json();
}
);Dependencies
- RxJS: For reactive programming and strategy composition
Inspiration
This library is inspired by the excellent Polly library for .NET, bringing similar resilience patterns to the JavaScript/TypeScript ecosystem.
