Comparing version 0.1.1 to 0.1.2
# Changelog | ||
## 1.0.1 - 2019-12-01 | ||
## 0.1.2 - 2019-12-12 | ||
- **fix**: wrong typing information for options to `retry.exponential()` | ||
## 0.1.1 - 2019-12-01 | ||
- **fix**: jitter backoff not applying max delay correctly | ||
- **fix**: jitter backoff adding more than intended amount of jitter | ||
## 1.0.0 - 2019-11-24 | ||
## 0.1.0 - 2019-11-24 | ||
Initial Release |
@@ -27,3 +27,3 @@ "use strict"; | ||
next() { | ||
if (this.attempt >= this.options.maxAttempts) { | ||
if (this.attempt >= this.options.maxAttempts - 1) { | ||
return undefined; | ||
@@ -30,0 +30,0 @@ } |
@@ -13,5 +13,5 @@ "use strict"; | ||
const b = new ExponentialBackoff_1.ExponentialBackoff({ generator: ExponentialBackoffGenerators_1.noJitterGenerator, maxAttempts: 4 }); | ||
Backoff_test_1.expectDurations(b, [0, 128, 256, 512, 1024, undefined]); | ||
Backoff_test_1.expectDurations(b, [0, 128, 256, 512, undefined]); | ||
}); | ||
}); | ||
//# sourceMappingURL=ExponentialBackoff.test.js.map |
@@ -25,3 +25,3 @@ import { decorrelatedJitterGenerator } from './ExponentialBackoffGenerators'; | ||
next() { | ||
if (this.attempt >= this.options.maxAttempts) { | ||
if (this.attempt >= this.options.maxAttempts - 1) { | ||
return undefined; | ||
@@ -28,0 +28,0 @@ } |
@@ -11,5 +11,5 @@ import { expectDurations } from './Backoff.test'; | ||
const b = new ExponentialBackoff({ generator: noJitterGenerator, maxAttempts: 4 }); | ||
expectDurations(b, [0, 128, 256, 512, 1024, undefined]); | ||
expectDurations(b, [0, 128, 256, 512, undefined]); | ||
}); | ||
}); | ||
//# sourceMappingURL=ExponentialBackoff.test.js.map |
@@ -65,3 +65,3 @@ import { IBackoff, IExponentialBackoffOptions } from './backoff/Backoff'; | ||
*/ | ||
exponential(options: IExponentialBackoffOptions<IRetryBackoffContext<unknown>>): this; | ||
exponential<S>(options: Partial<IExponentialBackoffOptions<S>>): this; | ||
/** | ||
@@ -68,0 +68,0 @@ * Sets the baackoff to use for retries. |
@@ -12,2 +12,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { stub, useFakeTimers } from 'sinon'; | ||
import { noJitterGenerator } from './backoff/Backoff'; | ||
import { Policy } from './Policy'; | ||
@@ -109,2 +110,10 @@ use(require('sinon-chai')); | ||
})); | ||
it('permits specifying exponential backoffs', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const s = stub().returns(1); | ||
expect(yield Policy.handleWhenResult(r => typeof r === 'number') | ||
.retry() | ||
.exponential({ generator: noJitterGenerator, maxAttempts: 2 }) | ||
.execute(s)).to.equal(1); | ||
expect(s).to.have.callCount(3); | ||
})); | ||
it('bubbles returns when retry attempts exceeded', () => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -111,0 +120,0 @@ const s = stub().returns(1); |
@@ -65,3 +65,3 @@ import { IBackoff, IExponentialBackoffOptions } from './backoff/Backoff'; | ||
*/ | ||
exponential(options: IExponentialBackoffOptions<IRetryBackoffContext<unknown>>): this; | ||
exponential<S>(options: Partial<IExponentialBackoffOptions<S>>): this; | ||
/** | ||
@@ -68,0 +68,0 @@ * Sets the baackoff to use for retries. |
@@ -14,2 +14,3 @@ "use strict"; | ||
const sinon_1 = require("sinon"); | ||
const Backoff_1 = require("./backoff/Backoff"); | ||
const Policy_1 = require("./Policy"); | ||
@@ -111,2 +112,10 @@ chai_1.use(require('sinon-chai')); | ||
})); | ||
it('permits specifying exponential backoffs', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const s = sinon_1.stub().returns(1); | ||
chai_1.expect(yield Policy_1.Policy.handleWhenResult(r => typeof r === 'number') | ||
.retry() | ||
.exponential({ generator: Backoff_1.noJitterGenerator, maxAttempts: 2 }) | ||
.execute(s)).to.equal(1); | ||
chai_1.expect(s).to.have.callCount(3); | ||
})); | ||
it('bubbles returns when retry attempts exceeded', () => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -113,0 +122,0 @@ const s = sinon_1.stub().returns(1); |
{ | ||
"name": "cockatiel", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"description": "A resilience and transient-fault-handling library that allows developers to express policies such as Backoff, Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner. Inspired by .NET Polly.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -21,3 +21,3 @@ # Cockatiel | ||
// Create a retry policy that'll try whatever function we execute 3 | ||
// times with an exponential backoff. | ||
// times with a randomized exponential backoff. | ||
const retry = Policy.handleAll() | ||
@@ -240,3 +240,3 @@ .retry() | ||
The crowd favorite. Takes in an options object, which can have any of these properties: | ||
The crowd favorite. By default, it uses a decorrelated jitter algorithm, which is a good default for most applications. Takes in an options object, which can have any of these properties: | ||
@@ -281,3 +281,5 @@ ```ts | ||
```ts | ||
// Use all the defaults: | ||
import { ExponentialBackoff, noJitterGenerator } from 'cockatiel'; | ||
// Use all the defaults. Decorrelated jitter, 30 seconds max delay, infinite attempts: | ||
const defaultBackoff = new ExponentialBackoff(); | ||
@@ -287,4 +289,14 @@ | ||
const limitedBackoff = new ExponentialBackoff({ maxDelay: 1000, initialDelay: 4 }); | ||
// Use a backoff without jitter | ||
const limitedBackoff = new ExponentialBackoff({ generator: noJitterGenerator }); | ||
``` | ||
Several jitter strategies are provided. This [AWS blog post](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) has more information around the strategies and why you might want to use them. The available jitter generators exported from `cockatiel` are: | ||
- `decorrelatedJitterGenerator` -- The default implementation, the one that [Polly.Contrib.WaitAndRetry uses](https://github.com/Polly-Contrib/Polly.Contrib.WaitAndRetry/tree/79224cff9670b159418f955af4d0a9ebc2a09778#new-jitter-recommendation) | ||
- `noJitterGenerator` -- Does not add any jitter | ||
- `fullJitterGenerator` -- Jitters between `[0, interval)` | ||
- `halfJitterGenerator` -- Jitters between `[interval / 2, interval)` | ||
### IterableBackoff | ||
@@ -363,4 +375,6 @@ | ||
// You can listen to an event, await a promise, or just check a synchronous value... | ||
token1.onCancellationRequested(() => console.log('source1 cancelled'); | ||
token1.cancellation().then(() => { /* ... */ }); | ||
token1.onCancellationRequested(() => console.log('source1 cancelled')); | ||
token1.cancellation().then(() => { | ||
/* ... */ | ||
}); | ||
@@ -373,3 +387,3 @@ if (token1.isCancellationRequested) { | ||
const source2 = new CancellationTokenSource(token1); | ||
source2.onCancellationRequested(() => console.log('source2 cancelled'); | ||
source2.onCancellationRequested(() => console.log('source2 cancelled')); | ||
@@ -376,0 +390,0 @@ // And, finally, cancel tokens, which will cascade down to all children: |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
422679
6350
868