network chunk v20

This commit is contained in:
andrei-mihnea-cerbu
2024-11-13 17:23:21 +02:00
parent f95b67f93d
commit 9baec7a7cb
41 changed files with 714 additions and 392 deletions
+75 -161
View File
@@ -1,214 +1,128 @@
import { Worker } from 'worker_threads';
import { fork, ChildProcess } from 'child_process';
import path from 'path';
import {WindowManager} from "./window_manager";
import { WindowManager } from "./window_manager";
export class WorkerManager {
private readonly pathToWorkerDir: string;
private windowManager: WindowManager
private workers: Worker[]; // Array to store running workers
private windowManager: WindowManager;
private workers: ChildProcess[];
private cleanupInProgress: boolean = false;
constructor(pathToWorkerDir: string, windowManager: WindowManager) {
this.pathToWorkerDir = pathToWorkerDir;
this.windowManager = windowManager;
this.workers = []; // Initialize the array to store workers
this.workers = [];
}
async startNetworkScannerWorker(udpPort: number, tcpPort: number, okPage: string, errorPage: string, databaseResetPage: string, userConfigPath: string, applicationInfoPath: string): Promise<void> {
return new Promise((resolve, reject) => {
const worker = new Worker(path.join(this.pathToWorkerDir, 'network_scanner_worker.js'), {
workerData: { udpPort, tcpPort, okPage, errorPage, databaseResetPage, userConfigPath, applicationInfoPath }, // Pass necessary data to the worker
});
this.workers.push(worker); // Store the worker reference
worker.on('message', (data) => {
if (data.type === 'changeContent') {
this.windowManager.changeContent(data.page);
}
});
worker.on('error', (err) => {
console.error('Network Scanner Worker error:', err);
worker.terminate();
this.removeWorker(worker);
reject(err); // Reject the promise if there's an error
});
worker.on('exit', (code) => {
console.log(`Network Scanner Worker exited with code ${code}`);
this.removeWorker(worker); // Remove worker reference when it exits
resolve(); // Resolve when the worker exits cleanly
});
return this.startForkedWorker('network_scanner_worker.js', {
UDP_PORT: udpPort.toString(),
TCP_PORT: tcpPort.toString(),
OK_PAGE: okPage,
ERROR_PAGE: errorPage,
DATABASE_RESET_PAGE: databaseResetPage,
USER_CONFIG_PATH: userConfigPath,
APPLICATION_INFO_PATH: applicationInfoPath
});
}
// Start the Directories Watcher Worker
async startDirectoriesWatchersWorker(memoryManagerPath: string, applicationInfoPath: string): Promise<void> {
return new Promise((resolve, reject) => {
const worker = new Worker(path.join(this.pathToWorkerDir, 'directories_watcher_worker.js'), {
workerData: { memoryManagerPath, applicationInfoPath }, // Pass the port to the worker
});
this.workers.push(worker); // Store the worker reference
worker.on('message', (data) => {
console.log('DirectoriesWatcher message:', data);
});
worker.on('error', (err) => {
console.error('DirectoriesWatcher error:', err);
worker.terminate();
this.removeWorker(worker);
reject(err); // Reject the promise if there's an error
});
worker.on('exit', (code) => {
console.log(`DirectoriesWatcher exited with code ${code}`);
this.removeWorker(worker); // Remove worker reference when it exits
resolve(); // Resolve when the worker exits cleanly
});
return this.startForkedWorker('directories_watcher_worker.js', {
MEMORY_MANAGER_PATH: memoryManagerPath,
APPLICATION_INFO_PATH: applicationInfoPath
});
}
// Start the Servers Worker (UDP and TCP servers)
async startServersWorker(host: string, udpPort: number, tcpPort: number): Promise<void> {
return new Promise((resolve, reject) => {
const worker = new Worker(path.join(this.pathToWorkerDir, 'servers_worker.js'), {
workerData: { HOST: host, USER_UDP_PORT: udpPort, USER_TCP_PORT: tcpPort }, // Pass host and ports to the worker
});
this.workers.push(worker); // Store the worker reference
worker.on('message', (data) => {
console.log('Servers Worker message:', data);
});
worker.on('error', (err) => {
console.error('Servers Worker error:', err);
worker.terminate();
this.removeWorker(worker);
reject(err); // Reject the promise if there's an error
});
worker.on('exit', (code) => {
console.log(`Servers Worker exited with code ${code}`);
this.removeWorker(worker); // Remove worker reference when it exits
resolve(); // Resolve when the worker exits cleanly
});
return this.startForkedWorker('servers_worker.js', {
HOST: host,
USER_UDP_PORT: udpPort.toString(),
USER_TCP_PORT: tcpPort.toString()
});
}
// Start the Users Info Worker
async startResourceCoordinatorWorker(usersConfigPath: string, applicationInfoPath: string, memoryManagerPath: string, queueManagerPath: string, tcpPort: number): Promise<void> {
return new Promise((resolve, reject) => {
const worker = new Worker(path.join(this.pathToWorkerDir, 'resource_coordinator_worker.js'), {
workerData: {
usersConfigPath,
applicationInfoPath,
memoryManagerPath,
queueManagerPath,
tcpPort
}, // Pass necessary parameters to the worker
});
this.workers.push(worker); // Store the worker reference
worker.on('message', (data) => {
console.log('Users Info Worker message:', data);
});
worker.on('error', (err) => {
console.error('Users Info Worker error:', err);
worker.terminate();
this.removeWorker(worker);
reject(err); // Reject the promise if there's an error
});
worker.on('exit', (code) => {
console.log(`Users Info Worker exited with code ${code}`);
this.removeWorker(worker); // Remove worker reference when it exits
resolve(); // Resolve when the worker exits cleanly
});
return this.startForkedWorker('resource_coordinator_worker.js', {
USERS_CONFIG_PATH: usersConfigPath,
APPLICATION_INFO_PATH: applicationInfoPath,
MEMORY_MANAGER_PATH: memoryManagerPath,
QUEUE_MANAGER_PATH: queueManagerPath,
TCP_PORT: tcpPort.toString()
});
}
// Start the Backup Retrieval Worker
async startBackupRetrievalWorker(
userConfigPath: string,
applicationInfoPath: string,
clientPort: number,
destinationPath: string
): Promise<void> {
return new Promise(async (resolve, reject) => {
const worker = new Worker(path.join(this.pathToWorkerDir, 'backup_retrieval_worker.js'), {
workerData: { userConfigPath, applicationInfoPath, clientPort, destinationPath }, // Pass parameters to the worker
});
this.workers.push(worker); // Store the worker reference
worker.on('message', async (data) => {
console.log('Backup Retrieval Worker message:', data);
await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait for 1 second
await this.windowManager.changeContent('main_menu');
await this.windowManager.showAlert(data.message);
});
worker.on('error', (err) => {
console.error('Backup Retrieval Worker error:', err);
worker.terminate();
this.removeWorker(worker);
reject(err); // Reject the promise if there's an error
});
worker.on('exit', (code) => {
console.log(`Backup Retrieval Worker exited with code ${code}`);
this.removeWorker(worker); // Remove worker reference when it exits
resolve(); // Resolve when the worker exits cleanly
});
async startBackupRetrievalWorker(userConfigPath: string, applicationInfoPath: string, clientPort: number, destinationPath: string): Promise<void> {
return this.startForkedWorker('backup_retrieval_worker.js', {
USER_CONFIG_PATH: userConfigPath,
APPLICATION_INFO_PATH: applicationInfoPath,
CLIENT_PORT: clientPort.toString(),
DESTINATION_PATH: destinationPath
});
}
async startAnnouncementWorker(applicationInfoPath: string, clientPort: number, message: string): Promise<void> {
return this.startForkedWorker('send_announcement_worker.js', {
APPLICATION_INFO_PATH: applicationInfoPath,
CLIENT_PORT: clientPort.toString(),
MESSAGE: message
});
}
private async startForkedWorker(scriptName: string, envData: { [key: string]: string }): Promise<void> {
return new Promise((resolve, reject) => {
const worker = new Worker(path.join(this.pathToWorkerDir, 'send_announcement_worker.js'), {
workerData: { applicationInfoPath, clientPort, message }, // Pass necessary data to the worker
const worker = fork(path.join(this.pathToWorkerDir, scriptName), {
execArgv: ['--max-old-space-size=4096'],
env: { ...process.env, ...envData }
});
this.workers.push(worker); // Store the worker reference
this.workers.push(worker);
worker.on('message', async (data) => {
await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait for 1 second
this.windowManager.changeContent('main_menu');
this.windowManager.showAlert(`${data.message}`)
worker.on('message', (data: unknown) => {
const message = data as { type: string, page?: string, message?: string };
if (message.type === 'changeContent' && message.page) {
this.windowManager.changeContent(message.page);
} else if (message.type === 'showAlert' && message.message) {
this.windowManager.showAlert(message.message);
} else {
console.log(`${scriptName} message:`, message);
}
});
worker.on('error', (err) => {
console.error('Announcement Worker error:', err);
worker.terminate();
console.error(`${scriptName} error:`, err);
worker.kill();
this.removeWorker(worker);
reject(err); // Reject the promise if there's an error
reject(err);
});
worker.on('exit', (code) => {
console.log(`Announcement Worker exited with code ${code}`);
this.removeWorker(worker); // Remove worker reference when it exits
resolve(); // Resolve when the worker exits cleanly
worker.on('exit', (code, signal) => {
this.removeWorker(worker);
if (code === 0) {
console.log(`${scriptName} exited successfully`);
resolve();
} else if (signal) {
console.log(`${scriptName} was killed with signal: ${signal}`);
} else {
console.error(`${scriptName} exited with code: ${code}`);
}
});
});
}
// Close all running workers
closeAllWorkers(): void {
if (this.cleanupInProgress) return;
this.cleanupInProgress = true;
console.log('Terminating all running workers...');
this.workers.forEach(worker => worker.terminate()); // Terminate each worker
this.workers = []; // Clear the array after terminating all workers
this.workers.forEach(worker => worker.kill());
this.workers = [];
}
// Helper method to remove a worker from the workers array when it exits
private removeWorker(worker: Worker): void {
private removeWorker(worker: ChildProcess): void {
const index = this.workers.indexOf(worker);
if (index > -1) {
this.workers.splice(index, 1); // Remove the worker from the array
this.workers.splice(index, 1);
}
}
}