{"id":15792869,"url":"https://github.com/jhegarty14/resilience4ts","last_synced_at":"2025-05-12T14:08:32.993Z","repository":{"id":214400156,"uuid":"736433235","full_name":"JHegarty14/resilience4ts","owner":"JHegarty14","description":"resilience4ts is a functional, distributed-first fault tolerance library for TypeScript inspired by resilience4j and Polly","archived":false,"fork":false,"pushed_at":"2024-09-25T23:01:42.000Z","size":1589,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-27T16:08:19.513Z","etag":null,"topics":["bulkhead","cache","circuit-breaker","concurrency","distributed-locking","distributed-systems","fallback","fault-tolerance","hedge","nestjs","rate-limiter","resilience","retry","timeout"],"latest_commit_sha":null,"homepage":"https://jhegarty14.github.io/resilience4ts/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JHegarty14.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-27T22:32:44.000Z","updated_at":"2024-08-29T22:19:41.000Z","dependencies_parsed_at":"2024-01-26T01:31:43.655Z","dependency_job_id":"fc9684da-f74f-431d-93f6-796565c4fce2","html_url":"https://github.com/JHegarty14/resilience4ts","commit_stats":{"total_commits":22,"total_committers":2,"mean_commits":11.0,"dds":"0.045454545454545414","last_synced_commit":"fceac41c605e2da6a67ad7be1ef8617b000b67a3"},"previous_names":["jhegarty14/resilience4ts"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JHegarty14%2Fresilience4ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JHegarty14%2Fresilience4ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JHegarty14%2Fresilience4ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JHegarty14%2Fresilience4ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JHegarty14","download_url":"https://codeload.github.com/JHegarty14/resilience4ts/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222658899,"owners_count":17018629,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bulkhead","cache","circuit-breaker","concurrency","distributed-locking","distributed-systems","fallback","fault-tolerance","hedge","nestjs","rate-limiter","resilience","retry","timeout"],"created_at":"2024-10-04T23:06:09.091Z","updated_at":"2024-11-02T12:06:57.507Z","avatar_url":"https://github.com/JHegarty14.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# resilience4ts\n\n`resilience4ts` is a suite of packages that provide ergonomic tools for building performant and safe distributed systems with Typescript. While there are other Typescript ports of Java libraries like Hystrix and resilience4j, or .NET packages like Polly, it is designed to be used specifically in highly-concurrent, distributed applications.\n\n\u003cp align=\"center\"\u003e\n\t\u003ca href=\"https://www.npmjs.com/forts/resilience4ts\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/@nestjs/core.svg\" alt=\"Package License\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/jhegarty14/resilience4ts\u003e target=\"_blank\"\u003e\u003cimg src=\"https://github.com/jhegarty14/resilience4ts/actions/workflows/ci-pipeline.yaml/badge.svg\" alt=\"CI/CD Checks\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Description\n\nFollowing in the footsteps of its namesake [resilience4j](https://resilience4j.readme.io/docs/getting-started), resilience4ts also aims to be a transparent fault-tolerance layer via higher-order functions (decorators).\n\nResilience4ts provides 10 core decorators for the following patterns:\n\n- `resilience4ts-bulkhead`: [Bulkhead pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/bulkhead)\n- `resilience4ts-circuitbreaker`: [Circuit Breaker pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker)\n- `resilience4ts-cache`: Provides distributed or request-scoped [Caching](https://learn.microsoft.com/en-us/azure/architecture/patterns/cache-aside)\n- `resilience4ts-concurrent-lock`: [Distributed Lock](https://www.dremio.com/wiki/distributed-locking/)\n- `resilience4ts-concurrent-queue`\n- `resilience4ts-hedge`: [Hedge pattern](https://www.linkedin.com/pulse/hedged-request-pattern-golang-harleen-mann/)\n- `resilience4ts-fallback`: [Fallback pattern](https://www.codecentric.de/wissens-hub/blog/resilience-design-patterns-retry-fallback-timeout-circuit-breaker)\n- `resilience4ts-rate-limiter`: [Rate-Limiting pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/rate-limiting-pattern)\n- `resilience4ts-retry`: [Retry pattern](https://dev.to/abh1navv/retry-pattern-in-microservices-4m39)\n- `resilience4ts-timeout`: [Timeout pattern](https://8thlight.com/insights/microservices-arent-magic-handling-timeouts)\n\n:rocket: The `@resilience4ts-all` package provides all of the above decorators in a single package, along with additional decorators for building reusable pipelines of decorators.\n\n:bulb: For effortless integration into NestJS applications, check out the `resilience4ts-nestjs` package!\n\n## Installation\n\n```bash\n$ npm install @forts/resilience4ts-all\n```\n\nOr to install individual packages:\n\n```bash\n$ npm install @forts/resilience4ts-bulkhead\n```\n\n```bash\n$ npm install @forts/resilience4ts-circuit-breaker\n```\n\n```bash\n$ npm install @forts/resilience4ts-cache\n```\n\n```bash\n$ npm install @forts/resilience4ts-concurrent-lock\n```\n\n```bash\n$ npm install @forts/resilience4ts-concurrent-queue\n```\n\n```bash\n$ npm install @forts/resilience4ts-hedge\n```\n\n```bash\n$ npm install @forts/resilience4ts-fallback\n```\n\n```bash\n$ npm install @forts/resilience4ts-rate-limiter\n```\n\n```bash\n$ npm install @forts/resilience4ts-retry\n```\n\n```bash\n$ npm install @forts/resilience4ts-timeout\n```\n\n```bash\n$ npm install @forts/resilience4ts-nestjs\n```\n\n## Usage Examples\n\n#### Bulkhead\n\n```typescript\nimport { Bulkhead } from '@forts/resilience4ts-bulkhead';\n\nconst myFunction = async (...args: unknown[]) =\u003e {\n  // do something\n};\n\nconst bulkhead = Bulkhead.of({\n  maxConcurrentCalls: 10,\n  maxWaitDuration: 1000,\n});\n\nconst decoratedFn = bulkhead.on(myFunction);\n\nconst result = await decoratedFn(...args);\n```\n\n#### Cache\n\n```typescript\nimport { Cache } from '@forts/resilience4ts-cache';\n\nconst cache = Cache.of('my-cache', {\n  extractKey: (...args: Parameters\u003cMyDecoratedMethod\u003e) =\u003e UniqueId, // Function that returns a unique id for the call from the decorated function args.\n  ttl: 1000, // Time to live in milliseconds.\n  maxCapacity: 100, // Maximum number of entries in the cache.\n});\n\nconst result = await cache.on(async () =\u003e {\n  // do something\n});\n```\n\n#### Request-Scoped Cache\n\n```typescript\nimport { RequestScopedCache, RequestScopedCacheType } from '@forts/resilience4ts-cache';\n\nconst cache = RequestScopedCache.of('my-cache', {\n  extractScope: (...args: Parameters\u003cMyDecoratedMethod\u003e) =\u003e Record\u003cstring, any\u003e, //Function that returns a \"scope\" to associate with the cache entry from the decorated function args.\n  extractKey: (...args: Parameters\u003cMyDecoratedMethod\u003e) =\u003e UniqueId, // Function that returns a unique id for the call.\n  type: RequestScopedCacheType.Local | RequestScopedCacheType.Distributed, // RequestScopedCacheType.Local uses a WeakMap to store the cache entries and is GC'd once the `extractScope` value falls out of scope, RequestScopedCacheType.Distributed uses a distributed cache.\n  clearOnRequestEnd: boolean, // Distributed only. Whether to clear the cache when the request ends, or persist it for the next request with the same scope.\n});\n\nconst result = await cache.on(async () =\u003e {\n  // do something\n});\n```\n\n#### CacheBuster\n\n```typescript\nimport { CacheBuster } from '@forts/resilience4ts-cache';\nimport { PredicateBuilder } from '@forts/resilience4ts-core';\n\n\nconst cacheBuster = CacheBuster.of('my-cache-buster', {\n\tinvalidatesKeys: (...args: any[]) =\u003e string | string[], // key(s) that should be invalidated upon decorated method execution.\n  invalidateOnException: true, // Whether to invalidate the cache if the decorated method throws an exception.\n  shouldInvalidate?: PredicateBuilder, // Constructs a predicate that is evaluated upon completion of the decorated method. If the predicate returns true, the cache is invalidated.\n});\n```\n\n#### Circuit Breaker\n\n```typescript\nimport { CircuitBreaker, CircuitBreakerStrategy } from '@forts/resilience4ts-circuit-breaker';\n\nconst circuitBreaker = CircuitBreaker.of('my-circuit-breaker', {\n  strategy: CircuitBreakerStrategy.Percentage,\n  threshold: 0.5,\n  interval: 1000 * 60 * 15,\n  minimumFailures: 3,\n  whitelist: [], // Error[]. If the decorated method throws an error that is in the whitelist, the circuit breaker will not record it as a failure.\n  circuitConnectionRetries: 3,\n  halfOpenLimit: 3,\n});\n\nconst result = await circuitBreaker.on(async () =\u003e {\n  // do something\n});\n```\n\n#### Concurrent Lock\n\n```typescript\nimport { ConcurrentLock } from '@forts/resilience4ts-concurrent-lock';\n\nconst lock = ConcurrentLock.of('my-lock', {\n  withKey: (...args: Parameters\u003cMyDecoratedMethod\u003e) =\u003e UniqueId,\n});\n\nconst result = await lock.on(async () =\u003e {\n  // do something\n});\n```\n\n#### Concurrent Queue\n\n```typescript\nimport { ConcurrentQueue } from '@forts/resilience4ts-concurrent-queue';\n\nconst queue = ConcurrentQueue.of('my-queue', {\n  withKey: (...args: Parameters\u003cMyDecoratedMethod\u003e) =\u003e UniqueId,\n});\n\nconst result = await queue.on(async () =\u003e {\n  // do something\n});\n```\n\n#### Hedge\n\n```typescript\nimport { Hedge } from '@forts/resilience4ts-hedge';\n\nconst hedge = Hedge.of('my-hedge', {\n  delay: 1000,\n});\n\nconst result = await hedge.on(async () =\u003e {\n  // do something\n});\n```\n\n#### Fallback\n\n```typescript\nimport { Fallback } from '@forts/resilience4ts-fallback';\n\nconst fallback = Fallback.of('my-fallback', {\n  shouldHandle?: PredicateBuilder,\n  fallbackAction: (...args: Parameters\u003cMyDecoratedMethod\u003e[]) =\u003e Promise\u003cMyDecoratedMethodReturn\u003e | MyDecoratedMethodReturn,\n});\n\nconst result = await fallback.on(async () =\u003e {\n  // do something\n});\n```\n\n#### Rate Limiter\n\n```typescript\nimport { RateLimiter } from '@forts/resilience4ts-rate-limiter';\n\nconst rateLimiter = RateLimiter.of('my-rate-limiter', {\n  permitLimit: 1000,\n  window: 1000,\n});\n\nconst result = await rateLimiter.on(async () =\u003e {\n  // do something\n});\n```\n\n#### Retry\n\n```typescript\nimport { Retry } from '@forts/resilience4ts-retry';\n\nconst retry = Retry.of('my-retry', {\n  maxAttempts: 3,\n  backoff: 1000,\n});\n\nconst result = await retry.on(async () =\u003e {\n  // do something\n});\n```\n\n#### Timeout\n\n```typescript\nimport { Timeout } from '@forts/resilience4ts-timeout';\n\nconst timeout = Timeout.of('my-timeout', {\n  timeout: 1000,\n});\n\nconst result = await timeout.on(async () =\u003e {\n  // do something\n});\n```\n\n## Roadmap\n\n### v0.1.0\n\n- [x] Bulkhead implmentation\n- [x] Circuit Breaker implementation\n- [x] Cache implementation\n- [x] Request-scoped implementation\n- [x] Concurrent lock implementation\n- [x] Hedge implementation\n- [x] Fallback implementation\n- [x] Rate Limiter implementation\n- [x] Retry implementation\n- [x] Timeout implementation\n- [x] NestJS package\n  - [x] Decorators\n- [x] documentation\n- [x] quick start examples\n  - [x] NestJS quickstart\n  - [ ] Express quickstart\n\n### v1.0.0\n\n- [ ] HttpClient\n  - [ ] supports cancellable requests\n- [ ] GrpcClient\n  - [ ] supports cancellable requests\n- [ ] DistributedContext module\n- [ ] Chaos Engineering module\n- [ ] Metrics\n  - [ ] Datadog integration\n  - [ ] MetricsController / Service for @forts/resilience4ts-nestjs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhegarty14%2Fresilience4ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjhegarty14%2Fresilience4ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhegarty14%2Fresilience4ts/lists"}