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); }; } } |