tencentcloud-edgeone-migration-nodejs-v2
Version:
tencentcloud cdn config copy to edgeone
348 lines • 16.3 kB
JavaScript
"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var _a, _Consumer_currentInstances, _Consumer_maxInstances;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Consumer = exports.InternalConsumer = exports.SelectResponse = void 0;
const process_1 = require("process");
const errors_1 = require("../errors");
const plugins_1 = require("../plugins");
const polaris_1 = require("../plugins/breaker/polaris");
const wr_1 = require("../plugins/lb/wr");
const console_1 = require("../plugins/logging/console");
const memory_1 = require("../plugins/registry/memory");
const nearby_1 = require("../plugins/router/polaris/nearby");
const rule_1 = require("../plugins/router/polaris/rule");
const polaris_2 = require("../plugins/weight/polaris");
const registry_1 = require("../registry");
const skeleton_1 = require("../skeleton");
const utils_1 = require("../utils");
const health_1 = require("./health");
const monitor_1 = require("./monitor");
const selector_1 = require("./selector");
const kSelector = Symbol("kSelector");
const kMonitor = Symbol("kMonitor");
const kHealth = Symbol("kHealth");
const kRegistry = Symbol("kRegistry");
class SelectResponse {
constructor(callee, instance, monitor) {
this.callee = callee;
this.instance = instance;
this[kMonitor] = monitor;
}
/**
* 上报调用结果
* @param success 是否调用成功
* @param cost 调用耗时(需大于等于 0,默认为 0)
* @param code 返回码(可选)
*/
update(success, cost = 0, code) {
this[kMonitor].update(this.callee.namespace, this.callee.service, this.instance, success, cost, code);
}
}
exports.SelectResponse = SelectResponse;
/**
* For internal use only.
* Use `Consumer` instead of `InternalConsumer`.
*/
class InternalConsumer extends skeleton_1.SkeletonClass {
/**
* Create Consumer
* @param plugins 插件
* @param options 配置参数(可选)
* @param logger Logger 对象共享,如不传则会自动创建
*/
constructor(plugins, options = {}, logger) {
const pluginList = InternalConsumer.mergePluginList(plugins, options);
super(pluginList, options, logger);
const naming = pluginList[plugins_1.PluginType.NamingService];
switch (naming.mode) {
case plugins_1.OperatingMode.Internal: {
this[kRegistry] = new registry_1.LocalRegistry(this[skeleton_1.kLogger], naming, this.plugins[plugins_1.PluginType.LocalRegistry], this.plugins[plugins_1.PluginType.StatReporter], undefined, options);
this[kHealth] = new health_1.Health(this[skeleton_1.kLogger], this[kRegistry], this.plugins[plugins_1.PluginType.LoadBalancer], this.plugins[plugins_1.PluginType.OutlierDetector], this.plugins[plugins_1.PluginType.StatReporter], options);
this[kRegistry].on("SyncInstanceStatus" /* SyncInstanceStatus */, (namespace, service, instance, status) => {
this[kHealth].changeStatus(namespace, service, instance, status, "[Registry], synchronized by naming");
});
this[kSelector] = new selector_1.InternalSelector(this[skeleton_1.kGlobal], this[skeleton_1.kLogger], this[kHealth], this[kRegistry], this.plugins[plugins_1.PluginType.ServiceRouter], this.plugins[plugins_1.PluginType.LoadBalancer], options);
this[kMonitor] = new monitor_1.InternalMonitor(this[skeleton_1.kLogger], this[kHealth], this[kRegistry], this.plugins[plugins_1.PluginType.WeightAdjuster], this.plugins[plugins_1.PluginType.StatReporter], this.plugins[plugins_1.PluginType.CircuitBreaker], options);
break;
}
case plugins_1.OperatingMode.External: {
this[kSelector] = new selector_1.ExternalSelector(naming);
this[kMonitor] = new monitor_1.ExternalMonitor(this[skeleton_1.kLogger], this.plugins[plugins_1.PluginType.StatReporter]);
break;
}
default: {
(0, utils_1.UNREACHABLE)();
}
}
}
static mergePluginList(plugins, options) {
const pluginList = {
[plugins_1.PluginType.NamingService]: plugins[plugins_1.PluginType.NamingService],
[plugins_1.PluginType.LocalRegistry]: plugins[plugins_1.PluginType.LocalRegistry] || new memory_1.MemoryOnlyRegistry(),
[plugins_1.PluginType.LoadBalancer]: plugins[plugins_1.PluginType.LoadBalancer] || new wr_1.WRLoadBalancer(),
[plugins_1.PluginType.ServiceRouter]: plugins[plugins_1.PluginType.ServiceRouter] || [new rule_1.PolarisRuleRouter(), new nearby_1.PolarisNearbyRouter()],
[plugins_1.PluginType.TraceLogging]: plugins[plugins_1.PluginType.TraceLogging] || [new console_1.ConsoleTraceLogging()],
[plugins_1.PluginType.WeightAdjuster]: plugins[plugins_1.PluginType.WeightAdjuster] || [],
[plugins_1.PluginType.OutlierDetector]: plugins[plugins_1.PluginType.OutlierDetector] || [],
[plugins_1.PluginType.StatReporter]: plugins[plugins_1.PluginType.StatReporter] || [],
[plugins_1.PluginType.CircuitBreaker]: plugins[plugins_1.PluginType.CircuitBreaker]
};
/**
* 在某些特殊场景下,为了避免死循环与内存开销,
* `NamingService` 与 `StatReporter` 插件实现在一个对象内
*/
const naming = pluginList[plugins_1.PluginType.NamingService];
if ((0, skeleton_1.isStatReporterPlugin)(naming)) {
pluginList[plugins_1.PluginType.StatReporter].push(naming);
}
/**
* `LoadBalancer` 插件不支持动态权重调整时,则不开启
*/
if (pluginList[plugins_1.PluginType.LoadBalancer].supportedWeightType !== 0 /* Dynamic */) {
options.enableDynamicWeights = false;
}
/**
* 如启用动态权重调整,又未配置插件实现时,使用默认实现
*/
if (options.enableDynamicWeights && pluginList[plugins_1.PluginType.WeightAdjuster].length === 0) {
pluginList[plugins_1.PluginType.WeightAdjuster] = [new polaris_2.PolarisDynamicWeight()];
}
/**
* 如启用节点熔断插件,又未配置插件实现时,使用默认实现
*/
if ((!options.breakerSwitch || options.breakerSwitch.period || options.breakerSwitch.realtime)
&& !pluginList[plugins_1.PluginType.CircuitBreaker]) {
pluginList[plugins_1.PluginType.CircuitBreaker] = new polaris_1.PolarisCircuitBreaker();
}
return pluginList;
}
/**
* 销毁(释放)所占资源
*
* @description
* dispose order:
* Monitor -> Health -> Selector -> Registry -> [plguins]
*
* @param sync 是否同步释放(可选)
*/
dispose(sync = false) {
var _b, _c;
const { [skeleton_1.kLogger]: logger, [skeleton_1.kDisposed]: disposed } = this;
if (disposed) {
return;
}
logger.trace("Consumer" /* Consumer */, Consumer.name, "dispose", undefined, "started");
this[kMonitor].dispose();
this[kHealth].dispose();
(_c = (_b = this[kSelector]).dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
this[kRegistry].dispose();
super.dispose(sync);
logger.trace("Consumer" /* Consumer */, Consumer.name, "dispose", undefined, "dispose completed");
}
async select(...args) {
const startTime = (0, process_1.uptime)();
let callee;
let caller;
let callArgs;
if (typeof args[0] === "string" && typeof args[1] === "string") {
const exactArgs = args;
callee = {
namespace: exactArgs[0],
service: exactArgs[1],
metadata: exactArgs[2]
};
const [, , metadata] = exactArgs;
if (metadata) {
caller = {
namespace: "",
service: "",
metadata
};
}
[, , , callArgs] = exactArgs;
}
else {
[callee, caller, callArgs] = args;
}
const { [skeleton_1.kLogger]: logger } = this;
const { transaction } = logger;
this[skeleton_1.kLogger].trace("Consumer" /* Consumer */, Consumer.name, "select", transaction, "caller is", caller, "callee is", callee, "with args:", callArgs);
let instance = null;
let err;
try {
this[skeleton_1.kMaybeAlreadyDisposed]();
instance = await this[kSelector].select(callee, caller, callArgs);
}
catch (e) {
err = e;
}
this[skeleton_1.kAPICollector]("Consumer.select", ((0, process_1.uptime)() - startTime) * utils_1.kSeconds, err);
if (err) {
logger.trace("Consumer" /* Consumer */, Consumer.name, "select", transaction, "exception", err);
throw err;
}
if (instance === null) {
logger.trace("Consumer" /* Consumer */, Consumer.name, "select", transaction, "not found matching instance");
return null;
}
logger.trace("Consumer" /* Consumer */, Consumer.name, "select", transaction, "selected instance is", instance);
return new SelectResponse(callee, instance, this[kMonitor]);
}
/**
* 获取全部服务实例
* @param namespace 服务名字空间
* @param service 服务名
*/
async list(namespace, service) {
const startTime = (0, process_1.uptime)();
const { [skeleton_1.kLogger]: logger } = this;
const { transaction } = logger;
if (logger.tracingEnabled) {
logger.trace("Consumer" /* Consumer */, Consumer.name, "list", transaction, `list ${namespace}.${service} instances`);
}
let err;
try {
this[skeleton_1.kMaybeAlreadyDisposed]();
const instances = await this[kSelector].list(namespace, service);
logger.trace("Consumer" /* Consumer */, Consumer.name, "list", transaction, "all instances:", instances);
return instances;
}
catch (e) {
err = e;
}
finally {
this[skeleton_1.kAPICollector]("Consumer.list", ((0, process_1.uptime)() - startTime) * utils_1.kSeconds, err);
}
logger.trace("Consumer" /* Consumer */, Consumer.name, "list", transaction, "exception", err);
throw err;
}
/**
* 获取服务规则路由
* @param namespace 服务名字空间
* @param service 服务名
*/
async rules(namespace, service) {
const startTime = (0, process_1.uptime)();
const { [skeleton_1.kLogger]: logger } = this;
const { transaction } = logger;
if (logger.tracingEnabled) {
logger.trace("Consumer" /* Consumer */, Consumer.name, "rules", transaction, `list ${namespace}.${service} rules`);
}
let err;
try {
this[skeleton_1.kMaybeAlreadyDisposed]();
const rules = await this[kSelector].rules(namespace, service);
logger.trace("Consumer" /* Consumer */, Consumer.name, "rules", transaction, "service rules:", rules);
return rules;
}
catch (e) {
err = e;
}
finally {
this[skeleton_1.kAPICollector]("Consumer.rules", ((0, process_1.uptime)() - startTime) * utils_1.kSeconds, err);
}
logger.trace("Consumer" /* Consumer */, Consumer.name, "rules", transaction, "exception", err);
throw err;
}
/**
* 强制刷新缓存
* @param namespace 服务名字空间
* @param service 服务名
* @param type 数据存储类别
*/
async update(namespace, service, type) {
const startTime = (0, process_1.uptime)();
const { [skeleton_1.kLogger]: logger } = this;
const { transaction } = logger;
if (logger.tracingEnabled) {
logger.trace("Consumer" /* Consumer */, Consumer.name, "update", transaction, `update ${namespace}.${service} ${type}`);
}
let err;
try {
this[skeleton_1.kMaybeAlreadyDisposed]();
const hasUpdated = await this[kRegistry].update(type, namespace, service);
logger.trace("Consumer" /* Consumer */, Consumer.name, "update", transaction, hasUpdated ? "no updates" : `updated ${type}`);
return hasUpdated;
}
catch (e) {
err = e;
}
finally {
this[skeleton_1.kAPICollector]("Consumer.update", ((0, process_1.uptime)() - startTime) * utils_1.kSeconds, err);
}
logger.trace("Consumer" /* Consumer */, Consumer.name, "update", transaction, "exception", err);
throw err;
}
}
exports.InternalConsumer = InternalConsumer;
class Consumer extends InternalConsumer {
/**
* Create Consumer
* @param plugins 插件
* @param options 配置参数(可选)
*/
constructor(plugins, options = {}) {
var _b;
super(plugins, options);
__classPrivateFieldSet(_b = Consumer, _a, __classPrivateFieldGet(_b, _a, "f", _Consumer_currentInstances) + 1, "f", _Consumer_currentInstances);
if (__classPrivateFieldGet(Consumer, _a, "f", _Consumer_currentInstances) >= __classPrivateFieldGet(Consumer, _a, "f", _Consumer_maxInstances)) {
(0, skeleton_1.emitMaxInstancesExceededWarning)("Consumer", __classPrivateFieldGet(Consumer, _a, "f", _Consumer_maxInstances));
}
}
/**
* 当前可实例化的最大次数
*/
static get maxInstances() {
return __classPrivateFieldGet(Consumer, _a, "f", _Consumer_maxInstances);
}
/**
* 设置可实例化的最大次数
* @param n 最大次数
*/
static setMaxInstances(n) {
if (typeof n !== "number" || n < 0 || Number.isNaN(n)) {
throw new errors_1.ArgumentError("|n| must be a non-negative number");
}
__classPrivateFieldSet(Consumer, _a, n, "f", _Consumer_maxInstances);
}
/**
* 销毁(释放)所占资源
* @param sync 是否同步释放(可选)
*/
dispose(sync = false) {
var _b;
if (this[skeleton_1.kDisposed]) {
return;
}
super.dispose(sync);
__classPrivateFieldSet(_b = Consumer, _a, __classPrivateFieldGet(_b, _a, "f", _Consumer_currentInstances) - 1, "f", _Consumer_currentInstances);
if (__classPrivateFieldGet(Consumer, _a, "f", _Consumer_currentInstances) < 0) {
(0, utils_1.UNREACHABLE)();
}
}
}
exports.Consumer = Consumer;
_a = Consumer;
_Consumer_currentInstances = { value: 0 };
_Consumer_maxInstances = { value: void 0 };
(() => {
let maxInstances = 10;
const { POLARIS_CONSUMER_INSTANCE_LIMIT } = process.env;
if (POLARIS_CONSUMER_INSTANCE_LIMIT !== undefined) {
maxInstances = parseInt(POLARIS_CONSUMER_INSTANCE_LIMIT, 10);
maxInstances = (maxInstances === 0 /** Unlimited */ ? Infinity : maxInstances);
}
_a.setMaxInstances(maxInstances);
})();
//# sourceMappingURL=index.js.map