@mdf.js/service-registry
Version:
MMS - API - Service Registry
173 lines • 6.76 kB
JavaScript
"use strict";
/**
* Copyright 2024 Mytra Control S.L. All rights reserved.
*
* Use of this source code is governed by an MIT-style license that can be found in the LICENSE file
* or at https://opensource.org/licenses/MIT.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RegisterFacade = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@mdf.js/core");
const logger_1 = require("@mdf.js/logger");
const cluster_1 = tslib_1.__importDefault(require("cluster"));
const events_1 = tslib_1.__importDefault(require("events"));
const Aggregator_1 = require("./Aggregator");
const Ports_1 = require("./Ports");
const Router_1 = require("./Router");
const types_1 = require("./types");
/**
* The RegisterFacade class provides a centralized solution for error monitoring across all
* components of an application. It acts as a facade over various underlying mechanisms to
* facilitate error aggregation, error information exposure through REST APIs, and error registry
* management.
*
* It integrates with:
* - Port: To handle inter-process communication for error information in clustered environments,
* distinguishing between master and worker processes.
* - Aggregator: To aggregate error information from different components of the application.
*
* This class also provides a REST API endpoint for accessing collected error information and
* supports operations for registering errors and clearing the error registry.
*/
class RegisterFacade extends events_1.default {
/**
* Create an instance of register manager
* @param options - registry options
*/
constructor(options) {
super();
this.options = options;
/**
* Event handler for error event
* @param error - Error triggered by the component
*/
this.errorEventHandler = (error) => {
if (this.listenerCount('error') > 0) {
this.emit('error', error);
}
};
this.logger = (0, logger_1.SetContext)(
// Stryker disable next-line all
options.logger || new logger_1.DebugLogger(`mdf:registry:errors:${this.name}`), this.name, this.componentId);
this.aggregator = new Aggregator_1.Aggregator(this.logger, this.options.maxSize, this.options.includeStack);
this.port = this.getPort(options, this.aggregator, this.logger);
this._router = new Router_1.Router(this.aggregator);
// Stryker disable next-line all
this.logger.debug(`New error registry instance created`);
}
/**
* Determines and initializes the appropriate Port instance based on the operating context
* (master, worker, or standalone process) to manage error registry communication and updates.
*
* @param options - Registry and operational options.
* @param aggregator - The aggregator instance for error collection.
* @param logger - Logger instance for logging activities.
* @returns An instance of Port or undefined if running in a standalone process.
*/
getPort(options, aggregator, logger) {
if (typeof options.isCluster === 'boolean') {
return options.isCluster && cluster_1.default.isPrimary
? new Ports_1.MasterPort(aggregator, logger, options.clusterUpdateInterval)
: new Ports_1.WorkerPort(aggregator, logger);
}
return undefined; // No port for standalone process
}
/** @returns The application name */
get name() {
return this.options.name;
}
/** @returns The application identifier */
get componentId() {
return this.options.instanceId;
}
/** @returns An Express router with access to registered errors */
get router() {
return this._router.router;
}
/** @returns Links offered by this service */
get links() {
return { [`${types_1.REGISTER_SERVICE_NAME}`]: `/${types_1.REGISTER_SERVICE_NAME}` };
}
/** @returns The health status of the component */
get status() {
return this.size > 0 ? core_1.Health.STATUS.WARN : core_1.Health.STATUS.PASS;
}
/** @returns Health checks for this service */
get checks() {
return {
[`${this.name}:errors`]: [
{
componentId: this.componentId,
processId: process.pid,
componentType: 'system',
observedValue: this.size,
observedUnit: 'errors',
status: this.status,
time: this.lastUpdate,
},
],
};
}
/**
* Registers one or multiple components to be monitored.
* @param component - The component or components to register.
*/
register(component) {
this.aggregator.register(component);
}
/**
* Adds an error to the registry, converting it to a structured format.
* @param error - The error to register.
*/
push(error) {
this.aggregator.push(error);
}
/** Clear the error registry */
clear() {
var _a;
this.aggregator.clear();
(_a = this.port) === null || _a === void 0 ? void 0 : _a.clear();
}
/** @returns Returns a combined list of all the registered errors */
get errors() {
return this.aggregator.errors;
}
/** @returns The current number of registered errors */
get size() {
return this.aggregator.size;
}
/** @returns Last update date */
get lastUpdate() {
return this.aggregator.lastUpdate;
}
/**
* Starts the error registry service, including the communication port and error event listeners.
*/
async start() {
var _a;
this.aggregator.on('error', this.errorEventHandler);
(_a = this.port) === null || _a === void 0 ? void 0 : _a.start();
// Stryker disable next-line all
this.logger.debug('Error registry service started');
}
/**
* Stops the error registry service, including halting communication and removing event listeners.
*/
async stop() {
var _a;
this.aggregator.off('error', this.errorEventHandler);
(_a = this.port) === null || _a === void 0 ? void 0 : _a.stop();
// Stryker disable next-line all
this.logger.debug('Error registry service stopped');
}
/** Closes the error registry service, performing cleanup actions as necessary. */
async close() {
this.aggregator.close();
await this.stop();
// Stryker disable next-line all
this.logger.debug('Error registry service closed');
}
}
exports.RegisterFacade = RegisterFacade;
//# sourceMappingURL=RegisterFacade.js.map