diff --git a/package.json b/package.json index 83061736f..f4bb3c649 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.0.9-qa", + "version": "2.0.9", "author": "Internxt ", "description": "Internxt Drive client UI", "license": "AGPL-3.0", @@ -28,7 +28,7 @@ "test:e2e": "playwright test --config=src/test", "type-check": "tsc --noEmit --pretty --skipLibCheck", "prepare": "husky install", - "reload-virtual-drive": "cd release/app && npm run reload-virtual-drive && cd ../.. && npm i", + "reload-virtual-drive": "cd release/app && npm run reload-virtual-drive && cd ../.. && yarn", "start:reload-bindings": "npm run reload-virtual-drive && npm run start" }, "lint-staged": { @@ -95,7 +95,8 @@ "win": { "target": [ "nsis" - ] + ], + "certificateSubjectName": "Internxt Universal Technologies SL" }, "linux": { "target": [ diff --git a/release/app/package.json b/release/app/package.json index 7ce1b7082..2f91bd86a 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "internxt-drive", - "version": "2.0.9-qa", + "version": "2.0.9", "description": "Internxt Drive client UI", "main": "./dist/main/main.js", "author": "Internxt ", diff --git a/src/apps/main/auth/handlers.ts b/src/apps/main/auth/handlers.ts index eb417215d..077d18da3 100644 --- a/src/apps/main/auth/handlers.ts +++ b/src/apps/main/auth/handlers.ts @@ -22,7 +22,7 @@ let isLoggedIn: boolean; export function setIsLoggedIn(value: boolean) { isLoggedIn = value; - getWidget()?.webContents.send('user-logged-in-changed', value); + getWidget()?.webContents?.send('user-logged-in-changed', value); } setIsLoggedIn(!!getUser()); diff --git a/src/apps/main/background-processes/sync-engine.ts b/src/apps/main/background-processes/sync-engine.ts index 8417f62a5..82548666e 100644 --- a/src/apps/main/background-processes/sync-engine.ts +++ b/src/apps/main/background-processes/sync-engine.ts @@ -31,7 +31,7 @@ async function healthCheck() { resolve(); }); - const millisecondsToWait = 2_000; + const millisecondsToWait = 8_000; setTimeout(() => { reject( @@ -72,9 +72,12 @@ function scheduleHeathCheck() { }); healthCheckSchedule = nodeSchedule.scheduleJob('*/30 * * * * *', async () => { - const workerIsPending = checkSyncEngineInProcess(5_000); - Logger.debug('Health check', workerIsPending ? 'Worker is pending' : 'Worker is running'); - if(!workerIsPending) { + const workerIsPending = checkSyncEngineInProcess(15_000); + Logger.debug( + 'Health check', + workerIsPending ? 'Worker is pending' : 'Worker is running' + ); + if (!workerIsPending) { await relaunchOnFail(); } }); @@ -254,7 +257,7 @@ export function fallbackSyncEngine() { export async function sendUpdateFilesInSyncPending(): Promise { try { if (worker?.webContents && !worker?.isDestroyed()) { - worker?.webContents.send('UPDATE_UNSYNC_FILE_IN_SYNC_ENGINE_PROCESS'); + worker?.webContents.send('UPDATE_UNSYNC_FILE_IN_SYNC_ENGINE_PROCESS'); } return []; } catch (err) { diff --git a/src/apps/main/fordwardToWindows.ts b/src/apps/main/fordwardToWindows.ts index 46d6d0c76..1a898c7d1 100644 --- a/src/apps/main/fordwardToWindows.ts +++ b/src/apps/main/fordwardToWindows.ts @@ -35,7 +35,6 @@ ipcMainDrive.on('FILE_PREPARING', (_, payload) => { ipcMainDrive.on('FILE_DOWNLOADED', (_, payload) => { const { nameWithExtension } = payload; - setIsProcessing(false); broadcastToWindows('sync-info-update', { action: 'DOWNLOADED', name: nameWithExtension, diff --git a/src/apps/sync-engine/BindingManager.ts b/src/apps/sync-engine/BindingManager.ts index 270663874..73a3d00bc 100644 --- a/src/apps/sync-engine/BindingManager.ts +++ b/src/apps/sync-engine/BindingManager.ts @@ -33,6 +33,9 @@ export class BindingsManager { private static readonly PROVIDER_NAME = 'Internxt'; private progressBuffer = 0; private controllers: IControllers; + private processingResolve?: (unknown?: unknown) => void; + private processingReject?: (unknown?: unknown) => void; + constructor( private readonly container: DependencyContainer, private readonly paths: { @@ -145,6 +148,10 @@ export class BindingsManager { finished = result.finished; Logger.debug('callback result', result); + if (result.progress > 1 || result.progress < 0) { + throw new Error('Result progress is not between 0 and 1'); + } + if (finished && result.progress === 0) { throw new Error('Result progress is 0'); } else if (this.progressBuffer == result.progress) { @@ -165,29 +172,28 @@ export class BindingsManager { }); } this.progressBuffer = 0; - - await this.controllers.notifyPlaceholderHydrationFinished.execute( - contentsId - ); } catch (error) { Logger.error('notify: ', error); Sentry.captureException(error); - await this.container.virtualDrive.closeDownloadMutex(); + await callback(false, ''); + // if (this.processingReject) this.processingReject(error); } + fs.unlinkSync(path); - await new Promise((resolve) => { - setTimeout(() => { - Logger.debug('timeout'); - resolve(true); - }, 500); - }); + await this.controllers.notifyPlaceholderHydrationFinished.execute( + contentsId + ); + if (this.processingResolve) this.processingResolve(); - fs.unlinkSync(path); ipcRenderer.send('CHECK_SYNC'); + Logger.debug('[Fetch Data Callback] Finish...', path); } catch (error) { Logger.error(error); Sentry.captureException(error); - callback(false, ''); + await callback(false, ''); + if (this.processingResolve) this.processingResolve(); + await this.container.virtualDrive.closeDownloadMutex(); + ipcRenderer.send('CHECK_SYNC'); } }, notifyMessageCallback: ( @@ -288,21 +294,25 @@ export class BindingsManager { try { Logger.debug('[Handle Hydrate Callback] Preparing begins', task.path); + // Crear una promesa que serĂ¡ resuelta por fetchDataCallback + const processingPromise = new Promise((resolve, reject) => { + this.processingResolve = resolve; + this.processingReject = reject; + }); + await this.container.virtualDrive.hydrateFile(task.path); - await new Promise((resolve) => { - setTimeout(() => { - Logger.debug('timeout'); - resolve(true); - }, 1000); - }); - Logger.debug('hydrate result'); + // Esperar hasta que fetchDataCallback resuelva o rechace la promesa + await processingPromise; + + Logger.debug('[Handle Hydrate Callback] Finish begins', task.path); } catch (error) { Logger.error(`error hydrating file ${task.path}`); Logger.error(error); Sentry.captureException(error); } }, + handleDehydrate: async (task: QueueItem) => { try { Logger.debug('Dehydrate', task); @@ -330,7 +340,7 @@ export class BindingsManager { queueManager, logWatcherPath ); - // queueManager.processAll(); + queueManager.processAll(); } async stop() { diff --git a/src/apps/sync-engine/dependency-injection/common/QueueManager.ts b/src/apps/sync-engine/dependency-injection/common/QueueManager.ts index 7a0816bd1..af6ec8606 100644 --- a/src/apps/sync-engine/dependency-injection/common/QueueManager.ts +++ b/src/apps/sync-engine/dependency-injection/common/QueueManager.ts @@ -15,11 +15,14 @@ export type QueueHandler = { handleChangeSize: HandleAction; }; +// const queueFilePath = path.join(__dirname, 'queue.json'); export class QueueManager implements IQueueManager { private _queue: QueueItem[] = []; private isProcessing = false; + // private queueFilePath = queueFilePath; + actions: HandleActions; constructor(handlers: QueueHandler) { @@ -30,12 +33,42 @@ export class QueueManager implements IQueueManager { changeSize: handlers.handleChangeSize, change: handlers.handleChange || (() => Promise.resolve()), }; + + // this.loadQueueFromFile(); } + // private saveQueueToFile(): void { + // const queue = this._queue.filter((item) => item.type !== 'hydrate'); + // fs.writeFileSync(this.queueFilePath, JSON.stringify(queue, null, 2)); + // Logger.debug('Queue saved to file.'); + // } + + // private loadQueueFromFile(): void { + // try { + // if (fs.existsSync(this.queueFilePath)) { + // const data = fs.readFileSync(this.queueFilePath, 'utf-8'); + // this._queue = JSON.parse(data); + // Logger.debug('Queue loaded from file.'); + // } + // } catch (error) { + // Logger.error('Failed to load queue from file:', error); + // } + // } + public enqueue(task: QueueItem): void { Logger.debug(`Task enqueued: ${JSON.stringify(task)}`); + // const existingTask = this._queue.find( + // (item) => item.path === task.path && item.type === task.type + // ); + // if (existingTask) { + // Logger.debug('Task already exists in queue. Skipping.'); + // this.processAll(); + + // return; + // } this._queue.push(task); this.sortQueue(); + // this.saveQueueToFile(); if (!this.isProcessing) { this.processAll(); } @@ -61,23 +94,37 @@ export class QueueManager implements IQueueManager { Logger.debug('No tasks in queue.'); return; } + const task = this._queue.shift(); if (!task) return; + + // this.saveQueueToFile(); + Logger.debug(`Processing task: ${JSON.stringify(task)}`); - switch (task.type) { - case 'add': - return await this.actions.add(task); - case 'hydrate': - return await this.actions.hydrate(task); - case 'dehydrate': - return await this.actions.dehydrate(task); - case 'change': - return await this.actions.change(task); - case 'changeSize': - return await this.actions.changeSize(task); - default: - Logger.debug('Unknown task type.'); - break; + + try { + switch (task.type) { + case 'add': + await this.actions.add(task); + break; + case 'hydrate': + await this.actions.hydrate(task); + break; + case 'dehydrate': + await this.actions.dehydrate(task); + break; + case 'change': + await this.actions.change(task); + break; + case 'changeSize': + await this.actions.changeSize(task); + break; + default: + Logger.debug('Unknown task type.'); + break; + } + } catch (error) { + Logger.error('Failed to process task:', task); } }