Skip to content

Commit

Permalink
Change: Progressive file retrieval implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
ArceDanielShok committed Jun 17, 2024
1 parent 9752c7d commit 1407b7a
Show file tree
Hide file tree
Showing 8 changed files with 553 additions and 45 deletions.
400 changes: 368 additions & 32 deletions src/apps/main/remote-sync/RemoteSyncManager.ts

Large diffs are not rendered by default.

76 changes: 67 additions & 9 deletions src/apps/main/remote-sync/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import {
sendUpdateFilesInSyncPending,
} from '../background-processes/sync-engine';
import { debounce } from 'lodash';
import configStore from '../config';

const SYNC_DEBOUNCE_DELAY = 3_000;


let initialSyncReady = false;
const driveFilesCollection = new DriveFilesCollection();
const driveFoldersCollection = new DriveFoldersCollection();
Expand Down Expand Up @@ -60,16 +60,66 @@ export async function getUpdatedRemoteItems() {
throw error;
}
}
export async function getUpdatedRemoteItemsByFolder(folderId: any) {
try {
const [allDriveFiles, allDriveFolders] = await Promise.all([
driveFilesCollection.getAll(),
driveFoldersCollection.getAll(),
]);

if (!allDriveFiles.success)
throw new Error('Failed to retrieve all the drive files from local db');

if (!allDriveFolders.success)
throw new Error('Failed to retrieve all the drive folders from local db');
return {
files: allDriveFiles.result,
folders: allDriveFolders.result,
};
} catch (error) {
reportError(error as Error, {
description:
'Something failed when updating the local db pulling the new changes from remote',
});
throw error;
}
}

ipcMain.handle('GET_UPDATED_REMOTE_ITEMS', async () => {
Logger.debug('[MAIN] Getting updated remote items');
return getUpdatedRemoteItems();
});

export function startRemoteSync(): Promise<void> {
return remoteSyncManager.startRemoteSync();
ipcMain.handle('GET_UPDATED_REMOTE_ITEMS_BY_FOLDER', async (folderId) => {
Logger.debug('[MAIN] Getting updated remote items');
return getUpdatedRemoteItemsByFolder(folderId);
});

// export async function startRemoteSync(): Promise<void> {
// await remoteSyncManager.startRemoteSync();
// }
// export async function startRemoteProgresiveSync(): Promise<void> {
export async function startRemoteSync(folderId?: number): Promise<void> {
try {
const { files: _files, folders } = await remoteSyncManager.startRemoteSync(
folderId
);
Logger.info('Remote sync started', folders?.length, 'folders');
Logger.info('Remote sync started', _files?.length, 'files');

if (folderId && folders && folders.length > 0) {
await Promise.all(
folders.map(async (folder) => await startRemoteSync(folder.id))
);
}
Logger.info('Remote sync finished');
return;
} catch (error) {
if (error instanceof Error) reportError(error);
}
}
ipcMain.handle('START_REMOTE_SYNC', async () => {
Logger.info('Received start remote sync event');
await startRemoteSync();
});

Expand All @@ -89,6 +139,7 @@ export async function updateRemoteSync(): Promise<void> {
// Wait before checking for updates, could be possible
// that we received the notification, but if we check
// for new data we don't receive it
Logger.info('Updating remote sync');
await sleep(2_000);
await startRemoteSync();
updateSyncEngine();
Expand All @@ -98,12 +149,12 @@ export async function fallbackRemoteSync(): Promise<void> {
fallbackSyncEngine();
}

export function checkSyncEngineInProcess (milliSeconds: number) {
export function checkSyncEngineInProcess(milliSeconds: number) {
const syncingStatus: RemoteSyncStatus = 'SYNCING';
const isSyncing = remoteSyncManager.getSyncStatus() === syncingStatus;
const recentlySyncing = remoteSyncManager.recentlyWasSyncing(milliSeconds);
return isSyncing || recentlySyncing; // syncing or recently was syncing
};
}

export function setIsProcessing(isProcessing: boolean) {
remoteSyncManager.isProcessRunning = isProcessing;
Expand Down Expand Up @@ -148,10 +199,18 @@ eventBus.on('RECEIVED_REMOTE_CHANGES', async () => {
eventBus.on('USER_LOGGED_IN', async () => {
Logger.info('Received user logged in event');

await remoteSyncManager.startRemoteSync().catch((error) => {
// await remoteSyncManager.startRemoteSync().catch((error) => {
// Logger.error('Error starting remote sync manager', error);
// reportError(error);
// });
try {
const userData = configStore.get('userData');
await startRemoteSync();
// traverse de esto
} catch (error) {
Logger.error('Error starting remote sync manager', error);
reportError(error);
});
if (error instanceof Error) reportError(error);
}
});

eventBus.on('USER_LOGGED_OUT', () => {
Expand Down Expand Up @@ -180,4 +239,3 @@ export async function checkSyncInProgress(milliSeconds: number) {
ipcMain.handle('CHECK_SYNC_IN_PROGRESS', async (_, milliSeconds: number) => {
return await checkSyncInProgress(milliSeconds);
});

2 changes: 1 addition & 1 deletion src/apps/main/usage/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class UserUsageService {
}

async calculateUsage(): Promise<Usage> {
const [driveUsage, photosUsage, limitInBytes] = await Promise.all([
const [driveUsage, photosUsage, limitInBytes] = await Promise.all([
this.getDriveUsage(),
this.getPhotosUsage(),
this.getLimit(),
Expand Down
4 changes: 4 additions & 0 deletions src/apps/shared/IPC/events/sync-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ export type SyncEngineInvocableFunctions = {
files: DriveFile[];
folders: DriveFolder[];
}>;
GET_UPDATED_REMOTE_ITEMS_BY_FOLDER: (folderId: number) => Promise<{
files: DriveFile[];
folders: DriveFolder[];
}>;
START_REMOTE_SYNC: () => Promise<void>;
};

Expand Down
5 changes: 2 additions & 3 deletions src/apps/sync-engine/BindingManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export class BindingsManager {
private progressBuffer = 0;
private controllers: IControllers;
private processingResolve?: (unknown?: unknown) => void;
private processingReject?: (unknown?: unknown) => void;

constructor(
private readonly container: DependencyContainer,
Expand Down Expand Up @@ -300,9 +299,9 @@ export class BindingsManager {
Logger.debug('[Handle Hydrate Callback] Preparing begins', task.path);

// Crear una promesa que será resuelta por fetchDataCallback
const processingPromise = new Promise((resolve, reject) => {
const processingPromise = new Promise((resolve, _reject) => {
this.processingResolve = resolve;
this.processingReject = reject;
// this.processingReject = reject;
});

await this.container.virtualDrive.hydrateFile(task.path);
Expand Down
32 changes: 32 additions & 0 deletions src/apps/utils/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,35 @@ export function getDateFromSeconds(seconds: number): Date {
export function getSecondsFromDateString(dateString: string): number {
return Math.trunc(new Date(dateString).valueOf() / 1000);
}

export function convertUTCToSpain(dateString: string) {
const date = new Date(dateString); // Crear un objeto Date a partir del string UTC

// Opciones de formato para España (CET/CEST)
const options: Intl.DateTimeFormatOptions = {
timeZone: 'Europe/Madrid',
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
fractionalSecondDigits: 3, // Incluye milisegundos
hour12: false, // Formato de 24 horas
};

// Formatear la fecha a la franja horaria de España
const formatter = new Intl.DateTimeFormat('es-ES', options);
const parts = formatter.formatToParts(date);

// Construir la fecha en el formato deseado
const formattedDate = `${
parts.find((part) => part?.type === 'year')?.value
}-${parts.find((part) => part.type === 'month')?.value}-${
parts.find((part) => part.type === 'day')?.value
}T${parts.find((part) => part.type === 'hour')?.value}:${
parts.find((part) => part.type === 'minute')?.value
}:${parts.find((part) => part.type === 'second')?.value}.000Z`;

return formattedDate;
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,51 @@ export class RemoteItemsGenerator {

return { files, folders };
}

async getFolderItems(
folderId: number
): Promise<{ files: ServerFile[]; folders: ServerFolder[] }> {
const updatedRemoteItems = await this.ipc.invoke(
'GET_UPDATED_REMOTE_ITEMS_BY_FOLDER',
folderId
);

const files = updatedRemoteItems.files.map<ServerFile>((updatedFile) => {
return {
bucket: updatedFile.bucket,
createdAt: updatedFile.createdAt,
encrypt_version: '03-aes',
fileId: updatedFile.fileId,
folderId: updatedFile.folderId,
id: updatedFile.id,
modificationTime: updatedFile.modificationTime,
name: updatedFile.name,
plainName: updatedFile.plainName,
size: updatedFile.size,
type: updatedFile.type ?? null,
updatedAt: updatedFile.updatedAt,
userId: updatedFile.userId,
status: updatedFile.status as ServerFileStatus,
uuid: updatedFile.uuid,
};
});

const folders = updatedRemoteItems.folders.map<ServerFolder>(
(updatedFolder) => {
return {
bucket: updatedFolder.bucket ?? null,
createdAt: updatedFolder.createdAt,
id: updatedFolder.id,
name: updatedFolder.name,
parentId: updatedFolder.parentId ?? null,
updatedAt: updatedFolder.updatedAt,
plain_name: updatedFolder.plainName ?? null,
status: updatedFolder.status as ServerFolderStatus,
uuid: updatedFolder.uuid,
};
}
);

return { files, folders };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ServerFileStatus } from '../../../shared/domain/ServerFile';
import { ServerFolderStatus } from '../../../shared/domain/ServerFolder';
import { Tree } from '../domain/Tree';
import { RemoteItemsGenerator } from './RemoteItemsGenerator';
import { Traverser } from './Traverser';

export class TreeProgresiveBuilder {
constructor(
private readonly remoteItemsGenerator: RemoteItemsGenerator,
private readonly traverser: Traverser
) {}

public setFilterStatusesToFilter(statuses: Array<ServerFileStatus>): void {
this.traverser.setFileStatusesToFilter(statuses);
}

public setFolderStatusesToFilter(statuses: Array<ServerFolderStatus>): void {
this.traverser.setFolderStatusesToFilter(statuses);
}
// hacer un recorrido progresivo empezar por el root y luego ir a los folders hijos y ejecutar el traverser

async run(): Promise<Tree> {
// obtener los items del root

// ejecutar el traverser

// ejecutar el recursiveTraverse para cada folder hijo
const items = await this.remoteItemsGenerator.getAll();

return this.traverser.run(items);
}
}

0 comments on commit 1407b7a

Please sign in to comment.