nope-js-node
Version:
NoPE Runtime for Nodejs. For Browser-Support please use nope-browser
299 lines (298 loc) • 12.6 kB
TypeScript
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2021-11-23 11:00:06
* @modify date 2021-11-25 08:47:21
* @desc [description]
*/
import { IServiceOptions, INopeEventEmitter, INopeObservable } from ".";
import { IAvailableServicesMsg, ICallOptions, IExtraData, IRequestRpcMsg, ITaskCancelationMsg } from "./nopeCommunication.interface";
import { IMapBasedMergeData } from "./nopeHelpers.interface";
import { INopePromise } from "./nopePromise.interface";
export type ValidDefaultSelectors = "first" | "master" | "dispatcher" | "host" | "free-ram" | "cpu-usage";
export declare const ValidDefaultSelectors: string[];
export type ValidSelectorFunction = (options: {
serviceName: string;
rpcManager: INopeRpcManager;
}) => Promise<string>;
export type ValidCallOptions = Partial<ICallOptions> & {
selector?: ValidSelectorFunction;
} & IExtraData;
export interface IRequestTaskWithCallback extends IRequestRpcMsg {
/**
* Callbacks, that are available in a Dispatcher.
*
* @author M.Karkowski
* @type {(({
* functionId: string;
* idx: number;
* deleteAfterCalling: boolean;
* } & ICallOptions)[])}
* @memberof IRequestTaskWithCallback
*/
callbacks: ({
functionId: string;
idx: number;
deleteAfterCalling: boolean;
} & ICallOptions)[];
}
/**
* The `rpcManager` is essentially a service registry.
*
* #### Service Registry
*
* A service registry is a tool used to store and manage information about available services in a distributed system. It is an important
* component of microservices architectures, where applications are divided into smaller, independent services that communicate over the network.
*
* A service registry serves as a central repository for metadata about each service, including its address, port number, protocol, and API
* version. When a service is started, it registers with the service registry, and when it is stopped, it is removed from it.
*
* Other services in the architecture can then query the Service Registry to find out which services are available and how they can
* communicate. This reduces the complexity of managing distributed systems and improves scalability and flexibility
*
* #### Service Broker
*
* A broker in the services world refers to a software tool or mechanism that acts as an intermediary between different services or applications.
* A broker is typically used in a service-oriented architecture (SOA) to facilitate and manage interaction and communication between different services.
*
* A broker provides various functions, such as message routing and transformation, monitoring, and security management. The broker can also
* perform tasks such as caching messages and routing requests to the most appropriate service.
*
* In an SOA environment, applications or services may communicate using different protocols and transports, and the broker acts as an intermediary
* to ensure that messages are exchanged correctly and reliably between the different systems. The broker can also help improve the scalability
* and flexibility of services by providing centralized control and management of service interactions.
*
* #### Implementation of a service registry and broker in `NoPE` by the `rpcManager`.
*
* A service in `NoPE` is defined by an `id`. This usually corresponds to a name with which the service is to be addressed.
*
* In order to implement the required functionalities of a service registry, the `rpcManager` has the following methods and attributes:
* - `registerService`: This can be used to register services. These are then made available to all participants of the NoPE network.
* - `unregisterService`: This can be used to remove services from the network.
* - The `services` property provides an overview of which services are available (including frequency and their parameters and description).
* - The `serviceExists` method can be used to test whether the service is available.
* - `performCall` execute a service. All relevant communications are mapped by the `rpcManager`. The user does not know which runtime provides the service.
* - The execution leads to a so called `task` which can be aborted by `cancelTask`. This leads to an exception at the calling unit.
* - If several service providers (NoPE-Runtime) are able to execute the service, the provider can be selected via a callback. For this purpose there are predefined `selectors`
* - `master` (see `connectivityManager`) the master must execute the process
* - `first`: any provider executes the serives (the first in the list)
* - `dispatcher`: a specific dispatcher must run the service (defined by its id)
* - `host`: a dispatcher on the defined host.
* - `cpu-usage`: the dispatcher with the least CPU usage
* - `free-ram`: The dispatcher with the lowest RAM usage
* - services with `callbacks` can also be hosted via a plugin
*
* @author M.Karkowski
* @export
* @interface INopeRpcManager
*/
export interface INopeRpcManager<T extends IServiceOptions = IServiceOptions> {
/**
* Flag, to show, that the System is ready
*
* @author M.Karkowski
* @memberof INopeRpcManager
*/
ready: INopeObservable<boolean>;
/**
* A Proxy to the provided Methods (including the Options)
*
* @author M.Karkowski
* @memberof INopeRpcManager
*/
methodInterfaceWithOptions: {
[index: string]: <T>(options: ICallOptions, ...args: any[]) => INopePromise<T>;
};
/**
* A Proxy to the provided Methods (without the Options)
*
* @author M.Karkowski
* @memberof INopeRpcManager
*/
methodInterface: {
[index: string]: <T>(...args: any[]) => INopePromise<T>;
};
/**
* Event, which is fired, if a task has been canceled.
* this is called after a the method.
*
* @author M.Karkowski
* @type {INopeEventEmitter<ITaskCancelationMsg>}
* @memberof INopeRpcManager
*/
onCancelTask: INopeEventEmitter<ITaskCancelationMsg>;
/**
* Element showing the available services.
*
* - `OriginalKey` = Dispatcher ID (string);
* - `OriginalValue` = Original Message (IAvailableServicesMsg);
* - `ExtractedKey` = Function ID (string);
* - `ExtractedValue` = FunctionOptions (T);
*
* @author M.Karkowski
* @type {IMapBasedMergeData<T>}
* @memberof INopeRpcManager
*/
services: IMapBasedMergeData<string, // Dispatcher ID
IAvailableServicesMsg, // Original Message
string, // Function ID
T>;
/**
* Function, that must be called if a dispatcher is is gone. This might be the
* case on slow connections or an a triggered disconnect.
*
* @author M.Karkowski
* @param {string} dispatcher
* @memberof INopeRpcManager
*/
removeDispatcher(dispatcher: string): void;
/**
* Function, that must be called, to update the available dispatchers.
*
* @author M.Karkowski
* @param {string} dispatcher
* @memberof INopeRpcManager
*/
updateDispatcher(dispatcher: IAvailableServicesMsg): void;
/**
* Function to cancel the given Task
*
* @author M.Karkowski
* @param {string} taskId The ID of the Task
* @param {Error} reason The Reason to Cancel the Task
* @param {void} quiet Disables Log or not.
* @memberof INopeRpcManager
*/
cancelTask(taskId: string, reason: Error, quiet?: boolean): Promise<boolean>;
/**
*
*
* @author M.Karkowski
* @param {string} serviceName
* @param {Error} reason
* @memberof INopeRpcManager
*/
cancelRunningTasksOfService(serviceName: string, reason: Error): void;
/**
* cancel all Tasks of the given dispatcher. If the Dispatcher isnt present,
* an error is raised
*
* @author M.Karkowski
* @param {string} dispatcher
* @param {Error} reason
* @memberof INopeRpcManager
*/
cancelRunningTasksOfDispatcher(dispatcher: string, reason: Error): void;
/**
* Simple helper to find the existing Services
*
* @author M.Karkowski
* @param {string} id The id of the service, which is used during registration
* @return {boolean} The result
* @memberof INopeRpcManager
*/
serviceExists(id: string): boolean;
/**
* Simple checker, to test, if this rpc-mananger is providing a service with the given id.
*
* @param id The id of the service, which is used during registration
* @return {boolean} The result
*/
isProviding(id: string): boolean;
/**
* Registers a function
*
* @author M.Karkowski
* @template T
* @param {(...args) => Promise<T>} func The Function
* @param options used during the service call.
* @return {(...args) => Promise<T>}
* @memberof INopeRpcManager
*/
registerService<T>(func: (...args: any[]) => Promise<T>, options: {
addNopeServiceIdPrefix?: boolean;
} & IServiceOptions): Promise<(...args: any[]) => Promise<T>>;
/**
* Helper to unregister an callback.
*
* @author M.Karkowski
* @param {(string | ((...args) => any))} func
* @return {Promise<boolean>} Success of the Operation
* @memberof INopeRpcManager
*/
unregisterService(func: string | ((...args: any[]) => any)): Promise<boolean>;
/**
* `performCall` execute a service. All relevant communications are mapped by the `rpcManager`. The user does not know which runtime provides the service.
* - The execution leads to a so called `task` which can be aborted by `cancelTask`. This leads to an exception at the calling unit.
* - If several service providers (NoPE-Runtime) are able to execute the service, the provider can be selected via a callback. For this purpose there are predefined `selectors`
* - `master` (see `connectivityManager`) the master must execute the process
* - `first`: any provider executes the serives (the first in the list)
* - `dispatcher`: a specific dispatcher must run the service (defined by its id)
* - `host`: a dispatcher on the defined host.
* - `cpu-usage`: the dispatcher with the least CPU usage
* - `free-ram`: The dispatcher with the lowest RAM usage
*
* @author M.Karkowski
* @param {string | string[]} serviceName The name of the service. If a list is provided, all services will be called at the same time using the same parameters
* @param {unknown[]} params Parameters
* @param {(Partial<ICallOptions> & {
* selector?: ValidSelectorFunction;
* quiet?: boolean;
* preventSelector?: boolean;
* })} options
* @return {INopePromise<T>}
* @memberof INopeRpcManager
*/
performCall<T>(serviceName: string | string[], params: unknown[], options?: ValidCallOptions | ValidCallOptions[]): INopePromise<T>;
/**
* Clear all Tasks.
*
* @author M.Karkowski
* @memberof INopeRpcManager
*/
clearTasks(): void;
/**
* Unregisters all registered Callbacks
*
* @author M.Karkowski
* @memberof INopeRpcManager
*/
unregisterAll(): void;
/**
* Resets the RPC Manager. This clears all running tasks and unregisters all callbacks
*
* @author M.Karkowski
* @memberof INopeRpcManager
*/
reset(): void;
/**
* Disposes the StatusManager and thereby,
*
* @author M.Karkowski
* @param {boolean} [quiet=false]
* @return {Promise<void>}
* @memberof INopeRpcManager
*/
dispose(): Promise<void>;
/**
* Description of a RPC-Manager
*/
toDescription(): {
services: {
all: T[];
internal: {
options: T;
func: (...args: any[]) => Promise<any>;
}[];
};
task: {
executing: string[];
requested: {
id: string;
service: string;
target: string;
timeout: any;
}[];
};
};
}