threads-message-broker
Version:
Message broker for threads
128 lines (127 loc) • 5.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ThreadsMessageBrokerMaster = void 0;
const worker_threads = require("worker_threads");
const uuid_1 = require("uuid");
const threads_message_broker_local_subscriber_1 = require("./threads-message-broker-local-subscriber");
const threads_message_broker_thread_subscriber_1 = require("./threads-message-broker-thread-subscriber");
class ThreadsMessageBrokerMaster {
constructor() {
if (worker_threads.isMainThread === false) {
throw new Error("Thread is not main");
}
this._threads_list = {};
this._subscribers_list = {};
}
subscribe(event_name, fn) {
if (this._subscribers_list[event_name] === undefined) {
this._subscribers_list[event_name] = {};
}
const id = (0, uuid_1.v4)();
const subscriber = new threads_message_broker_local_subscriber_1.ThreadsMessageBrokerLocalSubscriber(id, event_name, fn);
this._subscribers_list[event_name][id] = subscriber;
return `${event_name}${id}`;
}
unsubscribe(id_subscriber) {
const id = id_subscriber.substring(id_subscriber.length - 36, id_subscriber.length);
const event_name = id_subscriber.replace(id, "");
if (this._subscribers_list[event_name] !== undefined) {
delete this._subscribers_list[event_name][id];
if (Object.keys(this._subscribers_list[event_name]).length <= 0) {
delete this._subscribers_list[event_name];
}
}
}
addThread(worker_name, worker) {
if (this._threads_list[worker_name] !== undefined) {
throw new Error(`Worker ${worker_name} already exist`);
}
this._threads_list[worker_name] = worker;
worker.on("error", () => {
this._delete_worker(worker_name);
});
worker.on("exit", () => {
this._delete_worker(worker_name);
});
worker.on("message", (data) => {
const message = JSON.parse(data);
message.worker = worker_name;
if (message.command === "publish") {
if (this._subscribers_list[message.event] === undefined) {
return;
}
for (const id_subscriber in this._subscribers_list[message.event]) {
const subscriber = this._subscribers_list[message.event][id_subscriber];
if (subscriber.worker !== worker_name) {
subscriber.emit("publish", message.data);
}
}
}
if (message.command === "trigger") {
if (this._subscribers_list[message.event] === undefined) {
return;
}
for (const id_subscriber in this._subscribers_list[message.event]) {
const subscriber = this._subscribers_list[message.event][id_subscriber];
if (subscriber.worker !== worker_name) {
subscriber.emit("trigger");
}
}
}
if (message.command === "subscribe") {
if (this._subscribers_list[message.event] === undefined) {
this._subscribers_list[message.event] = {};
}
const subscriber = new threads_message_broker_thread_subscriber_1.ThreadsMessageBrokerThreadSubscriber(message.id_subscriber, message.event, worker_name, worker);
this._subscribers_list[message.event][message.id_subscriber] = subscriber;
}
if (message.command === "unsubscribe") {
this.unsubscribe(`${message.event}${message.id_subscriber}`);
}
});
}
removeThread(worker_name) {
if (this._threads_list[worker_name] === undefined) {
return;
}
this._delete_worker(worker_name);
}
_delete_worker(worker_name) {
this._threads_list[worker_name].removeAllListeners();
delete this._threads_list[worker_name];
for (const event_name in this._subscribers_list) {
const subscribers = this._subscribers_list[event_name];
for (const id_subscriber in subscribers) {
const subscriber = subscribers[id_subscriber];
if (subscriber.worker === worker_name) {
delete this._subscribers_list[event_name][id_subscriber];
}
}
if (Object.keys(this._subscribers_list[event_name]).length <= 0) {
delete this._subscribers_list[event_name];
}
}
}
publish(event_name, data, local_flag = false) {
if (this._subscribers_list[event_name] === undefined) {
return;
}
this._emit("publish", event_name, local_flag, data);
}
trigger(event_name, local_flag = false) {
if (this._subscribers_list[event_name] === undefined) {
return;
}
this._emit("trigger", event_name, local_flag);
}
_emit(type, event_name, local_flag = false, data = undefined) {
for (const id_subscriber in this._subscribers_list[event_name]) {
const subscriber = this._subscribers_list[event_name][id_subscriber];
if (subscriber.type !== "local" && local_flag === true) {
continue;
}
subscriber.emit(type, data);
}
}
}
exports.ThreadsMessageBrokerMaster = ThreadsMessageBrokerMaster;