overall v1
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { JsonManager } from './json_manager'; // Assuming this manages JSON configurations
|
||||
import { JsonManager } from './json_manager';
|
||||
import { TcpCommunicator } from "./tcp_communicator";
|
||||
import { operationCodes } from '../network/operation_codes'; // Assuming this holds operation codes
|
||||
import { parentPort } from 'worker_threads';
|
||||
import { operationCodes } from '../network/operation_codes';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import crypto from 'crypto';
|
||||
@@ -15,15 +14,30 @@ export class BackupRetrievalWorker {
|
||||
private encryptionKey: Buffer | null = null;
|
||||
private iv: Buffer | null = null;
|
||||
private tcpCommunicator: TcpCommunicator | null = null;
|
||||
private isBusy: boolean;
|
||||
private lastProcessedUserIndex: number;
|
||||
|
||||
constructor(userConfigPath: string, applicationInfoPath: string, clientPort: number, destinationPath: string) {
|
||||
this.userConfig = new JsonManager(userConfigPath);
|
||||
this.applicationInfo = new JsonManager(applicationInfoPath);
|
||||
this.clientPort = clientPort;
|
||||
this.destinationPath = destinationPath;
|
||||
this.isBusy = false;
|
||||
this.lastProcessedUserIndex = 0;
|
||||
}
|
||||
|
||||
async start(): Promise<void> {
|
||||
setInterval(async () => {
|
||||
if (!this.isBusy) {
|
||||
this.log('Start successfully. Processing backup tasks.');
|
||||
await this.processBackupTasks();
|
||||
}
|
||||
}, 10000); // Retry every 10 seconds if there's an error
|
||||
}
|
||||
|
||||
private async processBackupTasks(): Promise<void> {
|
||||
this.isBusy = true;
|
||||
|
||||
try {
|
||||
const userInfo = await this.userConfig.readValue('user_info');
|
||||
if (!userInfo || !userInfo.name) {
|
||||
@@ -41,46 +55,50 @@ export class BackupRetrievalWorker {
|
||||
|
||||
const activeUsersIp = await this.applicationInfo.readValue('users_ip');
|
||||
if (!activeUsersIp || !activeUsersIp.length) {
|
||||
parentPort?.postMessage({ success: false, message: 'No active users found.' });
|
||||
return;
|
||||
this.isBusy = false;
|
||||
throw new Error('No active users found.');
|
||||
}
|
||||
|
||||
// Process each user, starting from the last processed index
|
||||
let backupSuccessful = true;
|
||||
for (const ip of activeUsersIp) {
|
||||
for (let i = this.lastProcessedUserIndex; i < activeUsersIp.length; i++) {
|
||||
const ip = activeUsersIp[i];
|
||||
const success = await this.processBackupForIp(ip, userName);
|
||||
if (!success) {
|
||||
backupSuccessful = false;
|
||||
parentPort?.postMessage({ success: false, message: 'Backup could not be completed due to an internal error.' });
|
||||
this.lastProcessedUserIndex = i; // Remember where it stopped
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (backupSuccessful) {
|
||||
parentPort?.postMessage({ success: true, message: 'Backup successful.' });
|
||||
this.log('Backup retrieval completed successfully for all users.');
|
||||
this.lastProcessedUserIndex = 0; // Reset index to start from the beginning next cycle
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('Error in BackupRetrievalWorker:', error);
|
||||
parentPort?.postMessage({ success: false, message: `Backup could not be completed due to an internal error: ${error.message}` });
|
||||
this.log(error.message, 'error');
|
||||
}
|
||||
|
||||
this.isBusy = false;
|
||||
}
|
||||
|
||||
private async processBackupForIp(ip: string, userName: string): Promise<boolean> {
|
||||
this.tcpCommunicator = new TcpCommunicator(ip, this.clientPort);
|
||||
if (!await this.tcpCommunicator.connect()) {
|
||||
console.error(`Failed to connect to ${ip}`);
|
||||
this.log(`Failed to connect to ${ip}`, 'error');
|
||||
return false;
|
||||
}
|
||||
|
||||
const backupExists = await this.checkIfBackupExists(userName);
|
||||
if (!backupExists) {
|
||||
console.log(`No backup found for user ${userName} on IP ${ip}`);
|
||||
this.log(`No backup found for user ${userName} on IP ${ip}`);
|
||||
await this.tcpCommunicator.disconnect();
|
||||
return true; // Skip user if no backup found, do not mark as error
|
||||
}
|
||||
|
||||
const backupStructure = await this.requestBackupStructure(userName);
|
||||
if (!backupStructure || Object.keys(backupStructure).length === 0) {
|
||||
console.log(`No files found in backup structure for user ${userName} on IP ${ip}`);
|
||||
this.log(`No files found in backup structure for user ${userName} on IP ${ip}`);
|
||||
await this.tcpCommunicator.disconnect();
|
||||
return true; // Skip user if no files found, do not mark as error
|
||||
}
|
||||
@@ -88,7 +106,7 @@ export class BackupRetrievalWorker {
|
||||
for (const relativeFilePath of Object.keys(backupStructure)) {
|
||||
const fileRequestSuccess = await this.requestBackupFile(userName, relativeFilePath);
|
||||
if (!fileRequestSuccess) {
|
||||
console.error(`Failed to retrieve file ${relativeFilePath} from backup for user ${userName} on IP ${ip}`);
|
||||
this.log(`Failed to retrieve file ${relativeFilePath} from backup for user ${userName} on IP ${ip}`, 'error');
|
||||
await this.tcpCommunicator.disconnect();
|
||||
return false; // Stop if any file fails to be retrieved
|
||||
}
|
||||
@@ -133,7 +151,7 @@ export class BackupRetrievalWorker {
|
||||
|
||||
private saveFile(relativeFilePath: string, fileContent: string): boolean {
|
||||
if (!this.encryptionKey || !this.iv) {
|
||||
console.error('Encryption key or IV is not set.');
|
||||
this.log('Encryption key or IV is not set.', 'error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -141,7 +159,7 @@ export class BackupRetrievalWorker {
|
||||
try {
|
||||
encryptedBuffer = Buffer.from(fileContent, 'base64');
|
||||
} catch (error) {
|
||||
console.error('Error decoding base64 file content:', error);
|
||||
this.log(`Error decoding base64 file content: ${error}`, 'error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -150,7 +168,7 @@ export class BackupRetrievalWorker {
|
||||
const decipher = crypto.createDecipheriv('aes-256-cbc', this.encryptionKey, this.iv);
|
||||
decryptedContent = Buffer.concat([decipher.update(encryptedBuffer), decipher.final()]);
|
||||
} catch (error) {
|
||||
console.error('Error decrypting file:', error);
|
||||
this.log(`Error decrypting file: ${error}`, 'error');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -161,10 +179,10 @@ export class BackupRetrievalWorker {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
}
|
||||
fs.writeFileSync(fullFilePath, decryptedContent);
|
||||
console.log(`File saved successfully: ${fullFilePath}`);
|
||||
this.log(`File saved successfully: ${fullFilePath}`);
|
||||
return true;
|
||||
} catch (error: any) {
|
||||
console.error(`Error saving file ${relativeFilePath}: ${error.message}`);
|
||||
this.log(`Error saving file ${relativeFilePath}: ${error.message}`, 'error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -177,7 +195,17 @@ export class BackupRetrievalWorker {
|
||||
clearInterval(idResponseCheck);
|
||||
resolve(this.tcpCommunicator.getLastResult());
|
||||
}
|
||||
}, 100);
|
||||
}, 100); // Check every 100 milliseconds
|
||||
});
|
||||
}
|
||||
|
||||
// Unified logging function
|
||||
private log(message: string, level: 'log' | 'error' = 'log'): void {
|
||||
const prefix = '[BackupRetrievalWorker]';
|
||||
if (level === 'error') {
|
||||
console.error(`${prefix} ${message}`);
|
||||
} else {
|
||||
console.log(`${prefix} ${message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user