UNPKG

tencentcloud-edgeone-migration-nodejs-v2

Version:

tencentcloud cdn config copy to edgeone

72 lines 2.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NginxLoadBalancer = void 0; const utils_1 = require("../../utils"); const base_1 = require("./base"); /** * Smooth Weighted Round-Robin (SWRR) Load Balancer * (https://www.nginx.com/resources/glossary/round-robin-load-balancing/) * * @description * Algorithm: * 1. `S` = {S0, S1, S2, ..., Sn}, `EW(Si)` = Si.weight, `CW(Si)` = 0 * 2. CW(Si) = CW(Si) + EW(Si) * 3. Sx = Pick(Max(CW(Si))) * 4. CW(Sx) = CW(Sx) - Sum(EW(S)) * 5. return Sx */ class NginxLoadBalancer extends base_1.StatelessLoadBalancer { constructor() { super(...arguments); this.name = "NginxLoadBalancer"; this.callStat = Object.create(null); } /** * 1. 将各个实例的 `currentWeight` 增加 `effectiveWeight` * 2. 选取拥有最大 `currentWeight` 的实例 * 3. 将选取实例的 `currentWeight` 减少 `totalEffectiveWeight` */ choose(namespace, service, instances) { let callStat = this.callStat[`${namespace}.${service}`]; if (!callStat) { callStat = new WeakMap(); this.callStat[`${namespace}.${service}`] = callStat; this.randomChoose(namespace, service, instances); } let totalEffectiveWeight = 0; let bestWeight = -Infinity; let selectedInstance; for (let i = 0; i < instances.length; i += 1) { // eslint-disable-line @typescript-eslint/prefer-for-of const instance = instances[i]; const effectiveWeight = this.instanceWeight(instance); let currentWeight = callStat.get(instance) || 0; currentWeight += effectiveWeight; totalEffectiveWeight += effectiveWeight; if (!selectedInstance || bestWeight < currentWeight) { selectedInstance = instance; bestWeight = currentWeight; } callStat.set(instance, currentWeight); } if (selectedInstance) { callStat.set(selectedInstance, bestWeight - totalEffectiveWeight); return selectedInstance; } (0, utils_1.UNREACHABLE)(); } onStatusChange(namespace, service, instance, prevStatus) { if ( /* eslint-disable max-len */ (instance.status === 2 /* HalfClose */ && prevStatus === 1 /* HalfOpen */) /** `HalfOpen` ---> `HalfClose` */ || (instance.status === 0 /* Normal */ && prevStatus === 3 /* Fused */) /** `Fused` ---> `Normal` */ /* eslint-enable max-len */ ) { const callStat = this.callStat[`${namespace}.${service}`]; if (callStat) { callStat.delete(instance); } } } } exports.NginxLoadBalancer = NginxLoadBalancer; //# sourceMappingURL=swrr.js.map