coffee-core
Version:
Coffee IT API core library
94 lines • 3.22 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClientConnector = void 0;
const common_1 = require("@nestjs/common");
const operators_1 = require("rxjs/operators");
const DISCONNECTED_STATUS = 'disconnected';
class ClientConnector {
config;
client;
serviceName;
context;
statusSubscription;
destroyed = false;
reconnectInFlight = false;
constructor(config, client, serviceName, context) {
this.config = config;
this.client = client;
this.serviceName = serviceName;
this.context = context;
}
async connect() {
try {
await this.client.connect();
common_1.Logger.log(`Connected to ${this.serviceName}`, this.context);
this.watchStatusIfSupported();
}
catch (error) {
common_1.Logger.warn(`Initial connection to ${this.serviceName} failed, retrying in background: ${error}`, this.context);
this.scheduleBackgroundReconnect();
}
}
scheduleBackgroundReconnect() {
void this.connectWithRetry(0)
.then(() => {
if (!this.destroyed) {
this.watchStatusIfSupported();
}
})
.catch((error) => {
common_1.Logger.error(`Unexpected error while reconnecting to ${this.serviceName}: ${error}`, this.context);
});
}
destroy() {
this.destroyed = true;
this.statusSubscription?.unsubscribe();
this.statusSubscription = undefined;
}
watchStatusIfSupported() {
this.statusSubscription?.unsubscribe();
this.statusSubscription = this.client.status
.pipe((0, operators_1.filter)((status) => status === DISCONNECTED_STATUS))
.subscribe(() => {
void this.handleDisconnect();
});
}
async handleDisconnect() {
if (this.destroyed || this.reconnectInFlight) {
return;
}
this.reconnectInFlight = true;
try {
common_1.Logger.warn(`Disconnected from ${this.serviceName}, reconnecting...`, this.context);
await this.client.close();
await this.connectWithRetry(0);
}
finally {
this.reconnectInFlight = false;
}
}
async connectWithRetry(initialRetries) {
let retries = initialRetries;
while (!this.destroyed) {
try {
await this.client.connect();
common_1.Logger.log(`Connected to ${this.serviceName}`, this.context);
return;
}
catch {
await this.sleep(this.getRetryTime(retries));
retries += 1;
common_1.Logger.log(`Retrying ${this.serviceName} connection: ${retries}th time`, this.context);
}
}
}
getRetryTime(retries) {
const time = this.config.INITIAL_RETRY_TIMEOUT_MS * 2 ** retries;
return Math.min(time, this.config.MAX_RETRY_TIME_MS);
}
sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
}
exports.ClientConnector = ClientConnector;
//# sourceMappingURL=client-connector.js.map