Skip to content

Commit

Permalink
[PB-480] Feat: Track times (#269)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoanVicens authored Jun 23, 2023
1 parent ae8179f commit eff5539
Show file tree
Hide file tree
Showing 43 changed files with 928 additions and 284 deletions.
2 changes: 1 addition & 1 deletion src/main/analytics/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
TrackedWebdavServerEvents,
WebdavErrorContext,
} from '../../shared/IPC/events/webdav';
import uuid from 'uuid';

function platformShortName(platform: string) {
switch (platform) {
case 'darwin':
Expand Down
121 changes: 84 additions & 37 deletions src/main/analytics/webdav-handlers.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,92 @@
import { ipcMain, IpcMainEvent } from 'electron';
import Logger from 'electron-log';
import { FileCreatedDomainEvent } from '../../workers/webdav/modules/files/domain/FileCreatedDomainEvent';
import { ipcWebdav } from '../ipcs/webdav';
import { trackWebdavError, trackWebdavEvent } from './service';
import { WebdavDomainEvent } from '../../workers/webdav/modules/shared/domain/WebdavDomainEvent';
import { FileDownloadedDomainEvent } from '../../workers/webdav/modules/files/domain/FileDownloadedDomainEvent';
import { FileDeletedDomainEvent } from '../../workers/webdav/modules/files/domain/FileDeletedDomainEvent';
import { ipcWebdav, IpcWebdavFlow, IpcWebdavFlowErrors } from '../ipcs/webdav';
import {
trackHandledWebdavError,
trackWebdavError,
trackWebdavEvent,
} from './service';
import { WebdavErrorContext } from '../../shared/IPC/events/webdav';

function subscribeToDomainEvents() {
function subscribeTo<Event extends WebdavDomainEvent>(
eventName: Event['eventName'],
listener: (
event: IpcMainEvent,
domainEvent: ReturnType<Event['toPrimitives']>
) => void
) {
ipcMain.on(`webdav.${eventName}`, listener);
}
function subscribeToFlowEvents(ipc: IpcWebdavFlow) {
ipc.on('WEBDAV_FILE_DELETED', (_, payload) => {
const { name, type, size } = payload;

subscribeTo<FileCreatedDomainEvent>(
FileCreatedDomainEvent.EVENT_NAME,
(_, attributes) => {
trackWebdavEvent('Upload', attributes);
}
);
trackWebdavEvent('Delete', {
name,
type,
size,
});
});

ipc.on('WEBDAV_FILE_DOWNLOADED', (_, payload) => {
const { name, type, size, uploadInfo } = payload;

trackWebdavEvent('Upload', {
name,
type,
size,
elapsedTime: uploadInfo.elapsedTime,
});
});

ipc.on('WEBDAV_FILE_MOVED', (_, payload) => {
const { name, folderName } = payload;

// For some reason FileDownloadedDomainEvent.EVENT_NAME does not work ( ̄(エ) ̄)ゞ
subscribeTo<FileDownloadedDomainEvent>('file.downloaded', (_, attributes) => {
trackWebdavEvent('Preview', attributes);
trackWebdavEvent('Move', {
name,
folderName,
});
});

subscribeTo<FileDeletedDomainEvent>(FileDeletedDomainEvent.EVENT_NAME, () => {
trackWebdavEvent('Delete', {});
ipc.on('WEBDAV_FILE_OVERWRITED', (_, payload) => {
const { name } = payload;

trackWebdavEvent('Move', {
name,
});
});

ipc.on('WEBDAV_FILE_RENAMED', (_, payload) => {
const { name } = payload;

trackWebdavEvent('Rename', {
name,
});
});

ipc.on('WEBDAV_FILE_CLONNED', (_, payload) => {
const { name, type, size, uploadInfo } = payload;

trackWebdavEvent('Upload', {
name,
type,
size,
clonned: true,
elapsedTime: uploadInfo.elapsedTime,
});
});

ipc.on('WEBDAV_FILE_UPLOADED', (_, payload) => {
const { name, type, size, uploadInfo } = payload;

trackWebdavEvent('Upload', {
name,
type,
size,
elapsedTime: uploadInfo.elapsedTime,
});
});
}

function subscribeToFlowErrors(ipc: IpcWebdavFlowErrors) {
ipc.on('WEBDAV_FILE_UPLOADED_ERROR', (_, payload) => {
const { name, error } = payload;
trackWebdavError('Upload Error', { name, error });
});

ipc.on('WEBDAV_ACTION_ERROR', (_, error: Error, ctx: WebdavErrorContext) => {
const errorName = `${ctx.action} Error` as const;
trackHandledWebdavError(errorName, error, ctx);
});
}

Expand All @@ -44,15 +98,8 @@ function subscribeToServerEvents() {
ipcWebdav.on('WEBDAV_VIRTUAL_DRIVE_MOUNT_ERROR', (_, err: Error) => {
Logger.info('WEBDAV_VIRTUAL_DRIVE_MOUNT_ERROR', err.message);
});

ipcWebdav.on(
'WEBDAV_ACTION_ERROR',
(_, error: Error, ctx: WebdavErrorContext) => {
const errorName = `${ctx.action} Error` as const;
trackWebdavError(errorName, error, ctx);
}
);
}

subscribeToDomainEvents();
subscribeToFlowEvents(ipcWebdav);
subscribeToFlowErrors(ipcWebdav);
subscribeToServerEvents();
8 changes: 8 additions & 0 deletions src/main/ipcs/webdav.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ipcMain } from 'electron';
import {
WebdavFlowEvents,
WebdavFlowEventsErrors,
WebdavMainEvents,
WebDavProcessEvents,
} from '../../shared/IPC/events/webdav';
Expand All @@ -9,3 +11,9 @@ export const ipcWebdav = ipcMain as unknown as CustomIpc<
WebdavMainEvents,
WebDavProcessEvents
>;

type NoEvents = Record<string, (...args: Array<any>) => any>;

export type IpcWebdavFlow = CustomIpc<NoEvents, WebdavFlowEvents>;

export type IpcWebdavFlowErrors = CustomIpc<NoEvents, WebdavFlowEventsErrors>;
54 changes: 40 additions & 14 deletions src/shared/IPC/IPCs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,63 @@ import { IpcMainEvent } from 'electron';

type EventHandler = (...args: any) => any;

export type CustomIPCEvents<> = Record<string, EventHandler>;
export type CustomIPCEvents = Record<string, EventHandler>;

type NonVoidReturnHandler<T extends CustomIPCEvents> = {
[Property in keyof T as ReturnType<T[Property]> extends void
? never
: Property]: T[Property];
};

type VoidReturnHandler<T extends CustomIPCEvents> = {
[Property in keyof T as ReturnType<T[Property]> extends void
? Property
: never]: T[Property];
};

type VoidParamsHandler<T extends CustomIPCEvents> = {
[Property in keyof T as Parameters<T[Property]> extends never[]
? Property
: never]: T[Property];
};

export interface CustomIpc<
EmitedEvents extends CustomIPCEvents,
ListenedEvents extends CustomIPCEvents,
InvokableFunctions
ListenedEvents extends CustomIPCEvents
> {
send<Event extends keyof EmitedEvents>(
emit(event: keyof VoidParamsHandler<EmitedEvents>): void;

send<Event extends keyof VoidReturnHandler<EmitedEvents>>(
event: Event,
...args: Parameters<EmitedEvents[Event]>
...args: Parameters<VoidReturnHandler<EmitedEvents>[Event]>
): void;

emit(event: keyof EmitedEvents): void;

invoke<Event extends keyof InvokableFunctions>(
event: Event
): InvokableFunctions[Event];
invoke<Event extends keyof NonVoidReturnHandler<EmitedEvents>>(
event: Event,
...args: Parameters<NonVoidReturnHandler<EmitedEvents>[Event]>
): Promise<ReturnType<EmitedEvents[Event]>>;

on<Event extends keyof ListenedEvents>(
on<Event extends keyof VoidReturnHandler<ListenedEvents>>(
event: Event,
listener: (
event: IpcMainEvent,
...args: Parameters<ListenedEvents[Event]>
...args: Parameters<VoidReturnHandler<ListenedEvents>[Event]>
) => void
): void;

once<Event extends keyof ListenedEvents>(
once<Event extends keyof VoidReturnHandler<ListenedEvents>>(
event: Event,
listener: (
event: IpcMainEvent,
...args: Parameters<ListenedEvents[Event]>
...args: Parameters<VoidReturnHandler<ListenedEvents>[Event]>
) => void
): void;

handle<Event extends keyof NonVoidReturnHandler<ListenedEvents>>(
event: Event,
listener: (
event: IpcMainEvent,
...args: Parameters<NonVoidReturnHandler<ListenedEvents>[Event]>
) => void
): Promise<ReturnType<ListenedEvents[Event]>>;
}
61 changes: 58 additions & 3 deletions src/shared/IPC/events/webdav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const trackedEvents = [
'download',
'preview',
'move',
'rename',
] as const;
export type TrackedWebdavServerEvents = Capitalize<
(typeof trackedEvents)[number]
Expand All @@ -22,25 +23,79 @@ export type WebdavErrorContext = {
root: string;
};

export type WebDavProcessEvents = {
type WebdavServerEvents = {
WEBDAV_SERVER_START_SUCCESS: () => void;
WEBDAV_SERVER_START_ERROR: (err: Error) => void;
WEBDAV_SERVER_STOP_SUCCESS: () => void;
WEBDAV_SERVER_STOP_ERROR: (err: Error) => void;
WEBDAV_SERVER_ADDING_ROOT_FOLDER_ERROR: (err: Error) => void;
};

type WebdavVirtualDriveEvents = {
WEBDAV_VIRTUAL_DRIVE_MOUNTED_SUCCESSFULLY: () => void;
WEBDAV_VIRTUAL_DRIVE_MOUNT_ERROR: (err: Error) => void;
};

type UploadInfo = {
elapsedTime: number | undefined;
};

export type WebdavFlowEvents = {
WEBDAV_FILE_UPLOADED: (payload: {
name: string;
size: number;
type: string;
uploadInfo: UploadInfo;
}) => void;
WEBDAV_FILE_UPLOAD_PROGRESS: (payload: {
name: string;
progess: number;
uploadInfo: UploadInfo;
}) => void;
WEBDAV_FILE_DOWNLOADED: (payload: {
name: string;
size: number;
type: string;
uploadInfo: UploadInfo;
}) => void;
WEBDAV_FILE_DELETED: (payload: {
name: string;
size: number;
type: string;
}) => void;
WEBDAV_FILE_RENAMED: (payload: { name: string; oldName: string }) => void;
WEBDAV_FILE_MOVED: (payload: { name: string; folderName: string }) => void;
WEBDAV_FILE_OVERWRITED: (payload: { name: string }) => void;
WEBDAV_FILE_CLONNED: (payload: {
name: string;
size: number;
type: string;
uploadInfo: UploadInfo;
}) => void;
};

export type WebdavFlowEventsErrors = {
WEBDAV_FILE_UPLOADED_ERROR: (payload: {
name: string;
error: string;
}) => void;
WEBDAV_ACTION_ERROR: (err: Error, ctx: WebdavErrorContext) => void;
};

export type WebdavInvokableFunctions = {
GET_UPDATED_REMOTE_ITEMS: Promise<{
GET_UPDATED_REMOTE_ITEMS: () => Promise<{
files: DriveFile[];
folders: DriveFolder[];
}>;
START_REMOTE_SYNC: Promise<void>;
START_REMOTE_SYNC: () => Promise<void>;
};

export type WebDavProcessEvents = WebdavServerEvents &
WebdavVirtualDriveEvents &
WebdavFlowEvents &
WebdavFlowEventsErrors &
WebdavInvokableFunctions;

export type WebdavMainEvents = {
STOP_WEBDAV_SERVER_PROCESS: () => void;
};
33 changes: 33 additions & 0 deletions src/shared/types/Stopwatch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { performance } from 'perf_hooks';

export class Stopwatch {
private _start: number | undefined;
private _finish: number | undefined;

start() {
if (this._start) {
this._finish = undefined;
}

this._start = performance.now();
}

finish() {
if (!this._start) {
throw new Error('Cannot finish a stopwatch that have not started');
}
this._finish = performance.now();
}

elapsedTime(): number | undefined {
if (!this._start || !this._finish) {
return undefined;
}

return this._start - this._finish;
}

reset() {
this._start = this._finish = undefined;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export interface DependencyContainer {
fileDeleter: WebdavFileDeleter;
fileMover: WebdavFileMover;
fileCreator: WebdavFileCreator;
fileDonwloader: WebdavFileDownloader;
fileDownloader: WebdavFileDownloader;
fileMimeTypeResolver: WebdavFileMimeTypeResolver;
fileRenamer: WebdavFileRenamer;

Expand Down
Loading

0 comments on commit eff5539

Please sign in to comment.