Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 3x 3x 3x 13x 13x 13x 1x 2x 28x 14x 1x 1x 1x 13x 1x 1x 1x 1x 1x 12x 12x 12x 12x 1x | import { Logger } from '@jerryc/mini-logger';
export const logger = new Logger({ prefix: 'method-fuse' });
export interface MethodFuseOptions {
name?: string;
maxLoad?: number;
breakingTime?: number;
coolDownTime?: number;
}
export class MethodFuse {
// 保险丝名称
private name = 'unnamed';
// 最大负荷量,单位:调用次数
private maxLoad = 3;
// 当前负荷量,单位:调用次数
private curLoad = 0;
// 熔断持续时间,单位 ms
private breakingTime = 5000;
// 熔断状态
private breaked = false;
// 自动冷却时间,单位 ms
private coolDownTime = 1000;
private resetTimer = null;
constructor(Iparams: MethodFuseOptions = {}) {
Eif (params.name) this.name = params.name;
Eif (params.maxLoad) this.maxLoad = params.maxLoad;
Eif (params.breakingTime) this.breakingTime = params.breakingTime;
Iif (params.coolDownTime) this.coolDownTime = params.coolDownTime;
}
public reset() {
this.breaked = false;
this.curLoad = 0;
logger.info(`${this.name}-保险丝重置`);
}
public resetAfter(ms) {
if (this.resetTimer) clearTimeout(this.resetTimer);
this.resetTimer = setTimeout(() => this.reset(), ms);
}
public proxy(originMethod: (...any) => Promise<any>) {
const that = this;
return async function (this: any, ...args) {
if (that.breaked) {
const message = `${that.name}-保险丝已熔断,请稍后重试`;
logger.error(message);
throw new Error(message);
}
// 已达最大重试次数
if (that.curLoad >= that.maxLoad) {
that.breaked = true;
// 重置保险丝
that.resetAfter(that.breakingTime);
const message = `${that.name}-保险丝熔断,${that.breakingTime}ms 之后重铸`;
logger.error(message);
throw new Error(message);
}
// 自动冷却系统
that.resetAfter(that.coolDownTime);
// 允许当前请求通过保险丝,记录 +1
that.curLoad = that.curLoad + 1;
logger.info(`${that.name}-通过保险丝(${that.curLoad}/${that.maxLoad})`);
return originMethod.apply(this, ...args);
};
}
}
|