rocketmq-client-nodejs
Version:
RocketMQ Node.js Client
158 lines • 15.5 kB
JavaScript
"use strict";
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RpcClientManager = void 0;
const RpcClient_1 = require("./RpcClient");
const RPC_CLIENT_MAX_IDLE_DURATION = 30 * 60000; // 30 minutes
const RPC_CLIENT_IDLE_CHECK_PERIOD = 60000;
class RpcClientManager {
#rpcClients = new Map();
#baseClient;
#logger;
#clearIdleRpcClientsTimer;
constructor(baseClient, logger) {
this.#baseClient = baseClient;
this.#logger = logger;
this.#startUp();
}
#startUp() {
this.#clearIdleRpcClientsTimer = setInterval(() => {
this.#clearIdleRpcClients();
}, RPC_CLIENT_IDLE_CHECK_PERIOD);
}
#clearIdleRpcClients() {
for (const [endpoints, rpcClient] of this.#rpcClients.entries()) {
const idleDuration = rpcClient.idleDuration();
if (idleDuration > RPC_CLIENT_MAX_IDLE_DURATION) {
rpcClient.close();
this.#rpcClients.delete(endpoints);
this.#logger.info('[RpcClientManager] Rpc client has been idle for a long time, endpoints=%s, idleDuration=%s, clientId=%s', endpoints, idleDuration, RPC_CLIENT_MAX_IDLE_DURATION, this.#baseClient.clientId);
}
}
}
#getRpcClient(endpoints) {
let rpcClient = this.#rpcClients.get(endpoints);
if (!rpcClient) {
rpcClient = new RpcClient_1.RpcClient(endpoints, this.#baseClient.sslEnabled);
this.#rpcClients.set(endpoints, rpcClient);
}
return rpcClient;
}
close() {
// Clear idle check timer first
if (this.#clearIdleRpcClientsTimer) {
clearInterval(this.#clearIdleRpcClientsTimer);
}
// Close all RPC clients and clear the map
for (const [endpoints, rpcClient] of this.#rpcClients.entries()) {
try {
rpcClient.close();
}
catch (e) {
this.#logger.warn('Failed to close RPC client for endpoints=%s, clientId=%s, error=%s', endpoints.facade, this.#baseClient.clientId, e instanceof Error ? e.message : String(e));
}
}
this.#rpcClients.clear();
}
async queryRoute(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.queryRoute(request, metadata, duration);
}
async heartbeat(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.heartbeat(request, metadata, duration);
}
async sendMessage(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.sendMessage(request, metadata, duration);
}
async queryAssignment(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.queryAssignment(request, metadata, duration);
}
async receiveMessage(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.receiveMessage(request, metadata, duration);
}
async ackMessage(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.ackMessage(request, metadata, duration);
}
async forwardMessageToDeadLetterQueue(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.forwardMessageToDeadLetterQueue(request, metadata, duration);
}
async pullMessage(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.pullMessage(request, metadata, duration);
}
async updateOffset(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.updateOffset(request, metadata, duration);
}
async getOffset(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.getOffset(request, metadata, duration);
}
async queryOffset(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.queryOffset(request, metadata, duration);
}
async endTransaction(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.endTransaction(request, metadata, duration);
}
telemetry(endpoints, metadata) {
const rpcClient = this.#getRpcClient(endpoints);
return rpcClient.telemetry(metadata);
}
async changeInvisibleDuration(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.changeInvisibleDuration(request, metadata, duration);
}
async notifyClientTermination(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.notifyClientTermination(request, metadata, duration);
}
async recallMessage(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.recallMessage(request, metadata, duration);
}
async syncLiteSubscription(endpoints, request, duration) {
const rpcClient = this.#getRpcClient(endpoints);
const metadata = this.#baseClient.getRequestMetadata();
return await rpcClient.syncLiteSubscription(request, metadata, duration);
}
}
exports.RpcClientManager = RpcClientManager;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUnBjQ2xpZW50TWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQvUnBjQ2xpZW50TWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHOzs7QUFpQkgsMkNBQXdDO0FBR3hDLE1BQU0sNEJBQTRCLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDLGFBQWE7QUFDOUQsTUFBTSw0QkFBNEIsR0FBRyxLQUFLLENBQUM7QUFFM0MsTUFBYSxnQkFBZ0I7SUFDM0IsV0FBVyxHQUFHLElBQUksR0FBRyxFQUF3QixDQUFDO0lBQzlDLFdBQVcsQ0FBYTtJQUN4QixPQUFPLENBQVU7SUFDakIseUJBQXlCLENBQWlCO0lBRTFDLFlBQVksVUFBc0IsRUFBRSxNQUFlO1FBQ2pELElBQUksQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFDO1FBQzlCLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyx5QkFBeUIsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO1lBQ2hELElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzlCLENBQUMsRUFBRSw0QkFBNEIsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRCxvQkFBb0I7UUFDbEIsS0FBSyxNQUFNLENBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBRSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztZQUNsRSxNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDOUMsSUFBSSxZQUFZLEdBQUcsNEJBQTRCLEVBQUUsQ0FBQztnQkFDaEQsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNsQixJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMs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