Comparing version 0.1.2 to 0.1.3
# Changelog | ||
## 0.1.3 - 2019-01-26 | ||
- **feat**: add new `Policy.use()` decorator | ||
## 0.1.2 - 2019-12-12 | ||
@@ -4,0 +8,0 @@ |
@@ -102,2 +102,29 @@ import { IBreaker } from './breaker/Breaker'; | ||
static timeout(duration: number, strategy: TimeoutStrategy): TimeoutPolicy; | ||
/** | ||
* A decorator that can be used to wrap class methods and apply the given | ||
* policy to them. It also adds the last argument normally given in | ||
* {@link Policy.execute} as the last argument in the function call. | ||
* For example: | ||
* | ||
* ```ts | ||
* import { Policy } from 'cockatiel'; | ||
* | ||
* const retry = Policy.handleAll().retry().attempts(3); | ||
* | ||
* class Database { | ||
* @Policy.use(retry) | ||
* public getUserInfo(userId, context) { | ||
* console.log('Retry attempt number', context.attempt); | ||
* // implementation here | ||
* } | ||
* } | ||
* | ||
* const db = new Database(); | ||
* db.getUserInfo(3).then(info => console.log('User 3 info:', info)) | ||
* ``` | ||
* | ||
* Note that it will force the return type to be a Promise, since that's | ||
* what policies return. | ||
*/ | ||
static use(policy: IPolicy<unknown, never>): (_target: unknown, _key: string, descriptor: PropertyDescriptor) => void; | ||
protected constructor(options: Readonly<IBasePolicyOptions>); | ||
@@ -104,0 +131,0 @@ /** |
@@ -84,2 +84,40 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
/** | ||
* A decorator that can be used to wrap class methods and apply the given | ||
* policy to them. It also adds the last argument normally given in | ||
* {@link Policy.execute} as the last argument in the function call. | ||
* For example: | ||
* | ||
* ```ts | ||
* import { Policy } from 'cockatiel'; | ||
* | ||
* const retry = Policy.handleAll().retry().attempts(3); | ||
* | ||
* class Database { | ||
* @Policy.use(retry) | ||
* public getUserInfo(userId, context) { | ||
* console.log('Retry attempt number', context.attempt); | ||
* // implementation here | ||
* } | ||
* } | ||
* | ||
* const db = new Database(); | ||
* db.getUserInfo(3).then(info => console.log('User 3 info:', info)) | ||
* ``` | ||
* | ||
* Note that it will force the return type to be a Promise, since that's | ||
* what policies return. | ||
*/ | ||
static use(policy) { | ||
// tslint:disable-next-line: variable-name | ||
return (_target, _key, descriptor) => { | ||
const inner = descriptor.value; | ||
if (typeof inner !== 'function') { | ||
throw new Error(`Can only decorate functions with @cockatiel, got ${typeof inner}`); | ||
} | ||
descriptor.value = function (...args) { | ||
return policy.execute(context => inner.apply(this, [...args, context])); | ||
}; | ||
}; | ||
} | ||
/** | ||
* Allows the policy to additionally handles errors of the given type. | ||
@@ -86,0 +124,0 @@ * |
@@ -0,1 +1,7 @@ | ||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; | ||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); | ||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | ||
return c > 3 && r && Object.defineProperty(target, key, r), r; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -95,3 +101,23 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
})); | ||
it('applies Policy.use', () => __awaiter(void 0, void 0, void 0, function* () { | ||
class Calculator { | ||
double(n, context) { | ||
if (context.attempt < 2) { | ||
throw new Error('failed'); | ||
} | ||
return Object.assign({ n: n * 2 }, context); | ||
} | ||
} | ||
__decorate([ | ||
Policy.use(Policy.handleAll() | ||
.retry() | ||
.attempts(5)) | ||
], Calculator.prototype, "double", null); | ||
const c = new Calculator(); | ||
expect(yield c.double(2)).to.deep.equal({ | ||
n: 4, | ||
attempt: 2, | ||
}); | ||
})); | ||
}); | ||
//# sourceMappingURL=Policy.test.js.map |
@@ -102,2 +102,29 @@ import { IBreaker } from './breaker/Breaker'; | ||
static timeout(duration: number, strategy: TimeoutStrategy): TimeoutPolicy; | ||
/** | ||
* A decorator that can be used to wrap class methods and apply the given | ||
* policy to them. It also adds the last argument normally given in | ||
* {@link Policy.execute} as the last argument in the function call. | ||
* For example: | ||
* | ||
* ```ts | ||
* import { Policy } from 'cockatiel'; | ||
* | ||
* const retry = Policy.handleAll().retry().attempts(3); | ||
* | ||
* class Database { | ||
* @Policy.use(retry) | ||
* public getUserInfo(userId, context) { | ||
* console.log('Retry attempt number', context.attempt); | ||
* // implementation here | ||
* } | ||
* } | ||
* | ||
* const db = new Database(); | ||
* db.getUserInfo(3).then(info => console.log('User 3 info:', info)) | ||
* ``` | ||
* | ||
* Note that it will force the return type to be a Promise, since that's | ||
* what policies return. | ||
*/ | ||
static use(policy: IPolicy<unknown, never>): (_target: unknown, _key: string, descriptor: PropertyDescriptor) => void; | ||
protected constructor(options: Readonly<IBasePolicyOptions>); | ||
@@ -104,0 +131,0 @@ /** |
@@ -86,2 +86,40 @@ "use strict"; | ||
/** | ||
* A decorator that can be used to wrap class methods and apply the given | ||
* policy to them. It also adds the last argument normally given in | ||
* {@link Policy.execute} as the last argument in the function call. | ||
* For example: | ||
* | ||
* ```ts | ||
* import { Policy } from 'cockatiel'; | ||
* | ||
* const retry = Policy.handleAll().retry().attempts(3); | ||
* | ||
* class Database { | ||
* @Policy.use(retry) | ||
* public getUserInfo(userId, context) { | ||
* console.log('Retry attempt number', context.attempt); | ||
* // implementation here | ||
* } | ||
* } | ||
* | ||
* const db = new Database(); | ||
* db.getUserInfo(3).then(info => console.log('User 3 info:', info)) | ||
* ``` | ||
* | ||
* Note that it will force the return type to be a Promise, since that's | ||
* what policies return. | ||
*/ | ||
static use(policy) { | ||
// tslint:disable-next-line: variable-name | ||
return (_target, _key, descriptor) => { | ||
const inner = descriptor.value; | ||
if (typeof inner !== 'function') { | ||
throw new Error(`Can only decorate functions with @cockatiel, got ${typeof inner}`); | ||
} | ||
descriptor.value = function (...args) { | ||
return policy.execute(context => inner.apply(this, [...args, context])); | ||
}; | ||
}; | ||
} | ||
/** | ||
* Allows the policy to additionally handles errors of the given type. | ||
@@ -88,0 +126,0 @@ * |
"use strict"; | ||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; | ||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); | ||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | ||
return c > 3 && r && Object.defineProperty(target, key, r), r; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -97,3 +103,23 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
})); | ||
it('applies Policy.use', () => __awaiter(void 0, void 0, void 0, function* () { | ||
class Calculator { | ||
double(n, context) { | ||
if (context.attempt < 2) { | ||
throw new Error('failed'); | ||
} | ||
return Object.assign({ n: n * 2 }, context); | ||
} | ||
} | ||
__decorate([ | ||
Policy_1.Policy.use(Policy_1.Policy.handleAll() | ||
.retry() | ||
.attempts(5)) | ||
], Calculator.prototype, "double", null); | ||
const c = new Calculator(); | ||
chai_1.expect(yield c.double(2)).to.deep.equal({ | ||
n: 4, | ||
attempt: 2, | ||
}); | ||
})); | ||
}); | ||
//# sourceMappingURL=Policy.test.js.map |
{ | ||
"name": "cockatiel", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"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", |
@@ -52,2 +52,3 @@ # Cockatiel | ||
- [Policy.handleResultWhen(filter)](#policyhandleresultwhenfilter) | ||
- [Policy.use(policy)](#policyusepolicy) | ||
- [Policy.wrap(...policies)](#policywrappolicies) | ||
@@ -187,2 +188,27 @@ - [Policy.noop](#policynoop) | ||
### `Policy.use(policy)` | ||
A decorator that can be used to wrap class methods and apply the given policy to them. It also adds the last argument normally given in `Policy.execute` as the last argument in the function call. For example: | ||
```ts | ||
import { Policy } from 'cockatiel'; | ||
const retry = Policy.handleAll() | ||
.retry() | ||
.attempts(3); | ||
class Database { | ||
@Policy.use(retry) | ||
public getUserInfo(userId, context) { | ||
console.log('Retry attempt number', context.attempt); | ||
// implementation here | ||
} | ||
} | ||
const db = new Database(); | ||
db.getUserInfo(3).then(info => console.log('User 3 info:', info)); | ||
``` | ||
Note that it will force the return type to be a Promise, since that's what policies return. | ||
### `Policy.noop` | ||
@@ -189,0 +215,0 @@ |
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
432728
6532
894