nope/lib/dispatcher/nopeDispatcherManager.ts

228 lines
6.4 KiB
TypeScript
Raw Normal View History

2021-02-12 07:39:03 +00:00
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2021-02-09 11:26:58
2021-02-12 14:54:57 +00:00
* @modify date 2021-02-12 15:05:05
2021-02-12 07:39:03 +00:00
* @desc [description]
*/
import { INopeDispatcherOptions } from "../types/nope/nopeCommunication.interface";
import {
ENopeDispatcherStatus,
IDispatcherInfo
} from "../types/nope/nopeDispatcher.interface";
import { INopeModule, INopeModuleDescription } from "../types/nope/nopeModule.interface";
2021-02-12 07:39:03 +00:00
import { INopeObservable } from "../types/nope/nopeObservable.interface";
import { nopeDispatcher } from "./nopeDispatcher";
export type HostInfo = {
cpu: string;
cores: number;
os: string;
ram: number;
name: string;
disptachers: {
pid: number;
id: string;
status: ENopeDispatcherStatus;
timestamp: number;
}[];
status: ENopeDispatcherStatus;
instances: {
identifier: string,
status: ENopeDispatcherStatus,
dispatcher: string
}[];
timestamp: number;
};
/**
* Create an Enhanced Class, using the
*
* @export
* @class nopeDispatcherManager
* @extends {nopeDispatcher}
*/
export class nopeDispatcherManager extends nopeDispatcher {
public readonly onDispatcherWentOffline: INopeObservable<IDispatcherInfo[]>
public readonly onDispatcherWentOnline: INopeObservable<IDispatcherInfo[]>
private __knownDispatchers: Array<IDispatcherInfo>;
constructor(options: INopeDispatcherOptions,
_generateObservable: <T>() => INopeObservable<T>) {
2021-02-12 07:39:03 +00:00
super(options, _generateObservable);
this.onDispatcherWentOffline = _generateObservable();
this.onDispatcherWentOnline = _generateObservable();
this.__knownDispatchers = [];
}
public async _init() {
2021-02-12 07:39:03 +00:00
await super._init();
const _this = this;
// Initally store the known Dispatchers.
this.__knownDispatchers = this.externalDispatchers.getContent();
// Subscribe to Changes.
this.externalDispatchers.subscribe(dispatchers => {
const _newDispatchers = dispatchers.map(item => item.id);
const _oldDispatchers = _this.__knownDispatchers.map(item => item.id);
// Determine the newly Addded Dispatchers:
const _added = dispatchers.filter(dispatcher => !_oldDispatchers.includes(dispatcher.id));
// Determine the removed Dispatchers:
const _removed = _this.__knownDispatchers.filter(dispatcher => !_newDispatchers.includes(dispatcher.id));
_this.onDispatcherWentOnline.setContent(_added);
_this.onDispatcherWentOffline.setContent(_removed);
// Store the Updated Disaptchers.
_this.__knownDispatchers = dispatchers;
});
}
/**
* Funciton, used to determine the Dispatcher for the defined instance.
*
* @param {string} identifier Identifier of the Instance.
* @return {*} {(IDispatcherInfo | undefined)} Returns the IDispatcherInfo or undefined (if not found)
* @memberof nopeDispatcherManager
*/
public getDispatcherForInstance(identifier: string): IDispatcherInfo | undefined {
for (const [
dispatcher,
modules
] of this._mappingOfRemoteDispatchersAndInstances.entries()) {
for (const mod of modules) {
if (mod.identifier == identifier) {
return this._externalDispatchers.get(dispatcher);
}
}
}
return undefined;
}
/**
* Function to get all hosts.
*
* @return {*} {string[]}
* @memberof nopeDispatcherManager
*/
public getAllHosts(): string[] {
const hosts = new Set<string>();
for (const info of this._externalDispatchers.values()) {
hosts.add(info.host.name);
}
return Array.from(hosts);
}
2021-02-12 14:54:57 +00:00
/**
* Return the instances of the given Type.
*
* @param {string} type
* @return {*} {INopeModuleDescription[]}
* @memberof nopeDispatcherManager
*/
public async getInstancesOfType<I extends INopeModule>(type: string) {
2021-02-12 14:54:57 +00:00
const indentifier = this.availableInstances.getContent()
.filter(item => item.type == type)
.map(item => item.identifier);
const promises: Promise<I>[] = [];
for (const identifier of indentifier) {
promises.push(this.generateInstance({
identifier,
type,
params: []
}));
}
// Wait to generate all Instances.
const result = await Promise.all(promises);
return result;
}
public getInstanceDescription(identifier: string): INopeModuleDescription | null {
if (this._externalInstances.has(identifier)) {
return this._externalInstances.get(identifier);
}
return null;
}
public getInstanceDescriptionForType(identifier: string): INopeModuleDescription | null {
for (const description of this._externalInstances.values()) {
if (description.type === identifier) {
return description;
}
}
return null;
}
2021-02-12 07:39:03 +00:00
public getHostInfos(): {
[index: string]: HostInfo
} {
// Define a dataset, which contains the
// hosts.
const sorted: {
[index: string]: HostInfo
} = {};
for (const dispatcher of this._externalDispatchers.values()) {
// If required, define the Base Element.
if (sorted[dispatcher.host.name] === undefined) {
sorted[dispatcher.host.name] = {
cores: dispatcher.host.cores,
cpu: dispatcher.host.cpu,
name: dispatcher.host.name,
os: dispatcher.host.os,
disptachers: [],
instances: [],
ram: dispatcher.host.ram,
status: ENopeDispatcherStatus.HEALTHY,
timestamp: dispatcher.timestamp
};
}
if (this._mappingOfRemoteDispatchersAndInstances.has(dispatcher.id)) {
2021-02-12 07:39:03 +00:00
// Add the Instances:
for (const instance of this._mappingOfRemoteDispatchersAndInstances.get(dispatcher.id)) {
2021-02-12 07:39:03 +00:00
sorted[dispatcher.host.name].instances.push({
identifier: instance.identifier,
status: dispatcher.status,
dispatcher: dispatcher.id
});
}
}
2021-02-12 07:39:03 +00:00
// Define the state of overall state of this node.
sorted[dispatcher.host.name].status = Math.max(
sorted[dispatcher.host.name].status,
dispatcher.status
);
// Define the timestamp of the overall node.
sorted[dispatcher.host.name].timestamp = Math.min(
sorted[dispatcher.host.name].timestamp,
dispatcher.timestamp
);
// Store the Dispatcher Status
sorted[dispatcher.host.name].disptachers.push({
id: dispatcher.id,
status: dispatcher.status,
timestamp: dispatcher.timestamp,
pid: dispatcher.pid as number
});
}
return sorted;
}
}