2022-01-07 17:12:08 +00:00
|
|
|
/**
|
|
|
|
* @author Martin Karkowski
|
|
|
|
* @email m.karkowski@zema.de
|
|
|
|
* @create date 2022-01-06 07:15:22
|
|
|
|
* @modify date 2022-01-06 09:03:30
|
|
|
|
* @desc [description]
|
|
|
|
*/
|
|
|
|
|
|
|
|
import { generateId } from "../../helpers/idMethods";
|
|
|
|
import { defineNopeLogger } from "../../logger/getLogger";
|
2022-01-16 19:38:45 +00:00
|
|
|
import { ILogger, INFO } from "../../logger/index.browser";
|
2022-01-07 17:12:08 +00:00
|
|
|
import { DataPubSubSystem, PubSubSystem } from "../../pubSub";
|
|
|
|
import {
|
|
|
|
ICommunicationBridge,
|
|
|
|
IDataPubSubSystem,
|
|
|
|
INopeConnectivityManager,
|
|
|
|
INopeCore,
|
|
|
|
INopeDispatcherOptions,
|
2022-10-29 05:52:14 +00:00
|
|
|
INopeEventEmitter,
|
2022-01-07 17:12:08 +00:00
|
|
|
INopeInstanceManager,
|
|
|
|
INopeObservable,
|
|
|
|
INopeRpcManager,
|
2022-01-17 12:03:55 +00:00
|
|
|
IPubSubSystem,
|
2022-01-07 17:12:08 +00:00
|
|
|
} from "../../types/nope";
|
|
|
|
import { NopeConnectivityManager } from "../ConnectivityManager";
|
2022-10-29 05:52:14 +00:00
|
|
|
import {
|
|
|
|
generateAssignmentChecker,
|
|
|
|
NopeInstanceManager,
|
|
|
|
} from "../InstanceManager";
|
2022-01-07 17:12:08 +00:00
|
|
|
import { generateSelector, NopeRpcManager } from "../RpcManager";
|
|
|
|
|
|
|
|
export class NopeCore implements INopeCore {
|
|
|
|
protected _logger: ILogger;
|
|
|
|
|
|
|
|
public ready: INopeObservable<boolean>;
|
|
|
|
|
|
|
|
public readonly communicator: ICommunicationBridge;
|
|
|
|
public readonly eventDistributor: IPubSubSystem;
|
2022-01-10 06:52:05 +00:00
|
|
|
public readonly dataDistributor: IDataPubSubSystem;
|
2022-01-07 17:12:08 +00:00
|
|
|
public readonly connectivityManager: INopeConnectivityManager;
|
|
|
|
public readonly rpcManager: INopeRpcManager;
|
|
|
|
public readonly instanceManager: INopeInstanceManager;
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
public options: INopeDispatcherOptions,
|
2022-10-29 05:52:14 +00:00
|
|
|
protected generateEmitter: <T>() => INopeEventEmitter<T>,
|
2022-01-07 17:12:08 +00:00
|
|
|
protected generateObservable: <T>() => INopeObservable<T>,
|
|
|
|
public readonly id: string = null
|
|
|
|
) {
|
|
|
|
// Store the communicator:
|
|
|
|
this.communicator = options.communicator;
|
|
|
|
|
|
|
|
if (id == null) {
|
2022-01-16 19:38:45 +00:00
|
|
|
if (options.id) {
|
|
|
|
this.id = options.id;
|
|
|
|
} else {
|
|
|
|
this.id = generateId();
|
|
|
|
}
|
2022-01-07 17:12:08 +00:00
|
|
|
}
|
|
|
|
this._logger = defineNopeLogger(options.logger, `core.rpc-manager`);
|
|
|
|
|
2022-01-16 19:38:45 +00:00
|
|
|
if (this._logger?.enabledFor(INFO)) {
|
2022-01-07 17:12:08 +00:00
|
|
|
this._logger.info("setting up sub-systems.");
|
|
|
|
}
|
|
|
|
|
|
|
|
this.eventDistributor = new PubSubSystem();
|
2022-01-10 06:52:05 +00:00
|
|
|
this.dataDistributor = new DataPubSubSystem();
|
2022-01-07 17:12:08 +00:00
|
|
|
|
|
|
|
const defaultSelector = generateSelector(
|
|
|
|
options.defaultSelector || "first",
|
|
|
|
this
|
|
|
|
);
|
|
|
|
|
|
|
|
// Creating the Connectivity Manager:
|
|
|
|
this.connectivityManager = new NopeConnectivityManager(
|
|
|
|
options,
|
|
|
|
generateObservable,
|
|
|
|
this.id
|
|
|
|
);
|
|
|
|
|
|
|
|
// Create our RPC-Manger.
|
|
|
|
this.rpcManager = new NopeRpcManager(
|
|
|
|
options,
|
|
|
|
generateObservable,
|
|
|
|
defaultSelector,
|
|
|
|
this.id,
|
|
|
|
this.connectivityManager
|
|
|
|
);
|
|
|
|
|
|
|
|
// Create our Instance Manager
|
|
|
|
this.instanceManager = new NopeInstanceManager(
|
|
|
|
options,
|
2022-10-29 05:52:14 +00:00
|
|
|
generateEmitter,
|
2022-01-07 17:12:08 +00:00
|
|
|
generateObservable,
|
|
|
|
defaultSelector,
|
|
|
|
this.id,
|
|
|
|
this.connectivityManager,
|
|
|
|
this.rpcManager,
|
|
|
|
this
|
|
|
|
);
|
|
|
|
|
|
|
|
this.ready = generateObservable();
|
|
|
|
this.ready.getter = () => {
|
|
|
|
return (
|
|
|
|
this.connectivityManager.ready.getContent() &&
|
|
|
|
this.rpcManager.ready.getContent() &&
|
|
|
|
this.instanceManager.ready.getContent()
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2022-01-16 19:38:45 +00:00
|
|
|
const rcvExternally = generateId();
|
|
|
|
|
2022-01-10 06:52:05 +00:00
|
|
|
// 1. Subscribe to the events:
|
2022-10-10 06:17:36 +00:00
|
|
|
this.communicator.on("event", (msg) => {
|
2022-01-10 06:52:05 +00:00
|
|
|
if (msg.sender !== this.id) {
|
|
|
|
// split the Message in segments
|
2022-01-21 15:17:40 +00:00
|
|
|
const { path, data, ...options } = msg;
|
2022-01-16 19:38:45 +00:00
|
|
|
// Now, we know, that we have updated the data
|
|
|
|
// so, if there is an update, we will prevent this
|
|
|
|
// by setting the sender to the external id
|
|
|
|
options.sender = rcvExternally;
|
2022-01-10 06:52:05 +00:00
|
|
|
// Push the Data.
|
2022-01-21 15:17:40 +00:00
|
|
|
this.eventDistributor.emit(path, data, options);
|
2022-01-10 06:52:05 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.eventDistributor.onIncrementalDataChange.subscribe((item) => {
|
2022-01-16 19:38:45 +00:00
|
|
|
if (item.sender !== rcvExternally) {
|
2022-10-10 06:17:36 +00:00
|
|
|
this.communicator.emit("event", {
|
2022-01-16 19:38:45 +00:00
|
|
|
...item,
|
|
|
|
sender: this.id,
|
|
|
|
});
|
|
|
|
}
|
2022-01-10 06:52:05 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
// Link the Data-Distributor:
|
|
|
|
// 1. Subscribe to the changes:
|
2022-10-10 06:17:36 +00:00
|
|
|
this.communicator.on("dataChanged", (msg) => {
|
2022-01-10 06:52:05 +00:00
|
|
|
if (msg.sender !== this.id) {
|
|
|
|
// split the Message in segments
|
2022-01-21 15:17:40 +00:00
|
|
|
const { path: name, data, ...options } = msg;
|
2022-01-16 19:38:45 +00:00
|
|
|
|
|
|
|
// We will prevent to
|
|
|
|
options.sender = rcvExternally;
|
|
|
|
|
2022-01-10 06:52:05 +00:00
|
|
|
// Push the Data.
|
|
|
|
this.dataDistributor.pushData(name, data, options);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// 2. Enable emitting the updates
|
|
|
|
this.dataDistributor.onIncrementalDataChange.subscribe((item) => {
|
2022-01-16 19:38:45 +00:00
|
|
|
if (item.sender !== rcvExternally) {
|
2022-10-10 06:17:36 +00:00
|
|
|
this.communicator.emit("dataChanged", {
|
2022-01-16 19:38:45 +00:00
|
|
|
...item,
|
|
|
|
sender: this.id,
|
|
|
|
});
|
|
|
|
}
|
2022-01-10 06:52:05 +00:00
|
|
|
});
|
|
|
|
|
2022-01-07 17:12:08 +00:00
|
|
|
this.connectivityManager.ready.subscribe((_) => {
|
|
|
|
this.ready.forcePublish();
|
|
|
|
});
|
|
|
|
|
|
|
|
this.rpcManager.ready.subscribe((_) => {
|
|
|
|
this.ready.forcePublish();
|
|
|
|
});
|
|
|
|
|
|
|
|
this.instanceManager.ready.subscribe((_) => {
|
|
|
|
this.ready.forcePublish();
|
|
|
|
});
|
2022-04-20 12:20:48 +00:00
|
|
|
|
|
|
|
this.disposing = false;
|
2022-01-07 17:12:08 +00:00
|
|
|
}
|
|
|
|
|
2022-01-10 06:52:05 +00:00
|
|
|
// See interface description
|
2022-01-07 17:12:08 +00:00
|
|
|
public async dispose() {
|
2022-04-20 12:20:48 +00:00
|
|
|
this.disposing = true;
|
|
|
|
|
2022-01-07 17:12:08 +00:00
|
|
|
await this.ready.dispose();
|
|
|
|
await this.eventDistributor.dispose();
|
2022-01-10 06:52:05 +00:00
|
|
|
await this.dataDistributor.dispose();
|
2022-01-07 17:12:08 +00:00
|
|
|
await this.connectivityManager.dispose();
|
|
|
|
await this.rpcManager.dispose();
|
|
|
|
await this.instanceManager.dispose();
|
|
|
|
}
|
2022-04-20 12:20:48 +00:00
|
|
|
|
|
|
|
public disposing: boolean;
|
2022-01-07 17:12:08 +00:00
|
|
|
}
|