refactor v2
This commit is contained in:
@@ -0,0 +1,84 @@
|
|||||||
|
import { JsonManager } from './json_manager'; // Assuming this manages JSON configurations
|
||||||
|
import { TcpCommunicator } from "./tcp_communicator";
|
||||||
|
import { operationCodes } from '../network/operation_codes'; // Assuming this holds operation codes
|
||||||
|
import { parentPort } from 'worker_threads';
|
||||||
|
import {ParsedMessage} from "../network/message_handler";
|
||||||
|
|
||||||
|
export class AnnouncementSender {
|
||||||
|
private applicationInfo: JsonManager;
|
||||||
|
private readonly clientPort: number;
|
||||||
|
private message: string = '';
|
||||||
|
private tcpCommunicator: TcpCommunicator | null = null;
|
||||||
|
|
||||||
|
constructor(applicationInfoPath: string, clientPort: number) {
|
||||||
|
this.applicationInfo = new JsonManager(applicationInfoPath);
|
||||||
|
this.clientPort = clientPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
async start(message: string): Promise<void> {
|
||||||
|
console.log('AnnouncementWorker started.');
|
||||||
|
this.message = message;
|
||||||
|
try {
|
||||||
|
const activeUsersIp = await this.applicationInfo.readValue('users_ip');
|
||||||
|
if (!activeUsersIp || !activeUsersIp.length) {
|
||||||
|
throw new Error('No active users found.');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const ip of activeUsersIp) {
|
||||||
|
const success = await this.sendAnnouncementToIp(ip);
|
||||||
|
if (!success) {
|
||||||
|
throw new Error(`Failed to send announcement to all users.`);
|
||||||
|
}
|
||||||
|
console.log(`Announcement sent and confirmed successfully from ${ip}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
parentPort?.postMessage({ success: true, message: 'Announcement sent to all active users successfully.' });
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('Error in AnnouncementWorker:', error);
|
||||||
|
parentPort?.postMessage({ success: false, message: `A problem occurred: ${error.message}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('AnnouncementWorker finished.');
|
||||||
|
}
|
||||||
|
|
||||||
|
private async sendAnnouncementToIp(ip: string): Promise<boolean> {
|
||||||
|
this.tcpCommunicator = new TcpCommunicator(ip, this.clientPort);
|
||||||
|
if (!await this.tcpCommunicator.connect()) {
|
||||||
|
console.log(`Skipping user at IP ${ip} - unable to connect.`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the message metadata
|
||||||
|
const metaInfo = { message: this.message };
|
||||||
|
|
||||||
|
// Send the announcement message
|
||||||
|
const messageSent = await this.tcpCommunicator.sendMessage(operationCodes.SEND_ANNOUNCEMENT, metaInfo);
|
||||||
|
if (!messageSent) {
|
||||||
|
await this.tcpCommunicator.disconnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Await confirmation from the user
|
||||||
|
const response = await this.waitForResponse();
|
||||||
|
if (response?.operationCode === operationCodes.OK) {
|
||||||
|
await this.tcpCommunicator.disconnect();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If confirmation is not OK, disconnect and halt
|
||||||
|
await this.tcpCommunicator.disconnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async waitForResponse(): Promise<ParsedMessage | null> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const idResponseCheck = setInterval(async () => {
|
||||||
|
if (!this.tcpCommunicator) return null;
|
||||||
|
if (this.tcpCommunicator.hasResponseArrived()) {
|
||||||
|
clearInterval(idResponseCheck);
|
||||||
|
resolve(this.tcpCommunicator.getLastResult());
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -168,6 +168,35 @@ export class WorkerManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async startAnnouncementWorker(applicationInfoPath: string, clientPort: number, message: 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
|
||||||
|
});
|
||||||
|
|
||||||
|
this.workers.push(worker); // Store the worker reference
|
||||||
|
|
||||||
|
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('error', (err) => {
|
||||||
|
console.error('Announcement Worker error:', err);
|
||||||
|
worker.terminate();
|
||||||
|
this.removeWorker(worker);
|
||||||
|
reject(err); // Reject the promise if there's an error
|
||||||
|
});
|
||||||
|
|
||||||
|
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
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Close all running workers
|
// Close all running workers
|
||||||
closeAllWorkers(): void {
|
closeAllWorkers(): void {
|
||||||
console.log('Terminating all running workers...');
|
console.log('Terminating all running workers...');
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { workerData } from 'worker_threads';
|
||||||
|
import { AnnouncementSender} from "../helpers/announcement_sender";
|
||||||
|
|
||||||
|
// Destructure data passed from the main thread
|
||||||
|
const {
|
||||||
|
applicationInfoPath,
|
||||||
|
clientPort,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
applicationInfoPath: string,
|
||||||
|
clientPort: number,
|
||||||
|
message: string
|
||||||
|
} = workerData;
|
||||||
|
|
||||||
|
// Initialize the AnnouncementWorker
|
||||||
|
const announcementWorker = new AnnouncementSender(applicationInfoPath, clientPort);
|
||||||
|
|
||||||
|
// Start the announcement process and handle results
|
||||||
|
announcementWorker.start(message);
|
||||||
Reference in New Issue
Block a user