fixing logging in workers WIP 2

This commit is contained in:
Manav Rathi 2024-04-08 12:50:11 +05:30
parent a96ad6dfa2
commit da9a704094
No known key found for this signature in database
8 changed files with 74 additions and 156 deletions

View file

@ -1,72 +0,0 @@
import ElectronAPIs from "@ente/shared/electron";
import { WorkerSafeElectronService } from "@ente/shared/electron/service";
import { CustomError } from "@ente/shared/error";
import { addLogLine } from "@ente/shared/logging";
import { logError } from "@ente/shared/sentry";
import { convertBytesToHumanReadable } from "@ente/shared/utils/size";
import { ElectronFile } from "types/upload";
class ElectronImageProcessorService {
async convertToJPEG(fileBlob: Blob, filename: string): Promise<Blob> {
try {
const startTime = Date.now();
const inputFileData = new Uint8Array(await fileBlob.arrayBuffer());
const convertedFileData =
await WorkerSafeElectronService.convertToJPEG(
inputFileData,
filename,
);
addLogLine(
`originalFileSize:${convertBytesToHumanReadable(
fileBlob?.size,
)},convertedFileSize:${convertBytesToHumanReadable(
convertedFileData?.length,
)}, native conversion time: ${Date.now() - startTime}ms `,
);
return new Blob([convertedFileData]);
} catch (e) {
if (
e.message !==
CustomError.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED
) {
logError(e, "failed to convert to jpeg natively");
}
throw e;
}
}
async generateImageThumbnail(
inputFile: File | ElectronFile,
maxDimension: number,
maxSize: number,
): Promise<Uint8Array> {
try {
const startTime = Date.now();
const thumb = await ElectronAPIs.generateImageThumbnail(
inputFile,
maxDimension,
maxSize,
);
addLogLine(
`originalFileSize:${convertBytesToHumanReadable(
inputFile?.size,
)},thumbFileSize:${convertBytesToHumanReadable(
thumb?.length,
)}, native thumbnail generation time: ${
Date.now() - startTime
}ms `,
);
return thumb;
} catch (e) {
if (
e.message !==
CustomError.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED
) {
logError(e, "failed to generate image thumbnail natively");
}
throw e;
}
}
}
export default new ElectronImageProcessorService();

View file

@ -1,3 +1,4 @@
import ElectronAPIs from "@ente/shared/electron";
import { CustomError } from "@ente/shared/error";
import { addLogLine } from "@ente/shared/logging";
import { getFileNameSize } from "@ente/shared/logging/web";
@ -8,7 +9,6 @@ import { BLACK_THUMBNAIL_BASE64 } from "constants/upload";
import isElectron from "is-electron";
import * as FFmpegService from "services/ffmpeg/ffmpegService";
import HeicConversionService from "services/heicConversionService";
import imageProcessor from "services/imageProcessor";
import { ElectronFile, FileTypeInfo } from "types/upload";
import { isFileHEIC } from "utils/file";
import { getUint8ArrayView } from "../readerService";
@ -86,7 +86,7 @@ async function generateImageThumbnail(
) {
if (isElectron()) {
try {
return await imageProcessor.generateImageThumbnail(
return await generateImageThumbnailInElectron(
file,
MAX_THUMBNAIL_DIMENSION,
MAX_THUMBNAIL_SIZE,
@ -99,6 +99,39 @@ async function generateImageThumbnail(
}
}
const generateImageThumbnailInElectron = async (
inputFile: File | ElectronFile,
maxDimension: number,
maxSize: number,
): Promise<Uint8Array> => {
try {
const startTime = Date.now();
const thumb = await ElectronAPIs.generateImageThumbnail(
inputFile,
maxDimension,
maxSize,
);
addLogLine(
`originalFileSize:${convertBytesToHumanReadable(
inputFile?.size,
)},thumbFileSize:${convertBytesToHumanReadable(
thumb?.length,
)}, native thumbnail generation time: ${
Date.now() - startTime
}ms `,
);
return thumb;
} catch (e) {
if (
e.message !==
CustomError.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED
) {
logError(e, "failed to generate image thumbnail natively");
}
throw e;
}
};
export async function generateImageThumbnailUsingCanvas(
file: File | ElectronFile,
fileTypeInfo: FileTypeInfo,

View file

@ -53,8 +53,8 @@ import {
import { FileTypeInfo } from "types/upload";
import { default as ElectronAPIs } from "@ente/shared/electron";
import { workerBridge } from "@ente/shared/worker/worker-bridge";
import { t } from "i18next";
import imageProcessor from "services/imageProcessor";
import { getFileExportPath, getUniqueFileExportName } from "utils/export";
const WAIT_TIME_IMAGE_CONVERSION = 30 * 1000;
@ -452,8 +452,7 @@ export async function getRenderableImage(fileName: string, imageBlob: Blob) {
imageBlob.size,
)}`,
);
throw new Error("bypass");
convertedImageBlob = await imageProcessor.convertToJPEG(
convertedImageBlob = await convertToJPEGInElectron(
imageBlob,
fileName,
);
@ -485,6 +484,36 @@ export async function getRenderableImage(fileName: string, imageBlob: Blob) {
}
}
const convertToJPEGInElectron = async (
fileBlob: Blob,
filename: string,
): Promise<Blob> => {
try {
const startTime = Date.now();
const inputFileData = new Uint8Array(await fileBlob.arrayBuffer());
const convertedFileData = await workerBridge.convertToJPEG(
inputFileData,
filename,
);
addLogLine(
`originalFileSize:${convertBytesToHumanReadable(
fileBlob?.size,
)},convertedFileSize:${convertBytesToHumanReadable(
convertedFileData?.length,
)}, native conversion time: ${Date.now() - startTime}ms `,
);
return new Blob([convertedFileData]);
} catch (e) {
if (
e.message !==
CustomError.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED
) {
logError(e, "failed to convert to jpeg natively");
}
throw e;
}
};
export function isFileHEIC(exactType: string) {
return (
exactType.toLowerCase().endsWith(TYPE_HEIC) ||

View file

@ -1,44 +0,0 @@
import { inWorker } from "@/next/env";
import * as Comlink from "comlink";
import { wrap } from "comlink";
import { ElectronAPIsType } from "./types";
import { WorkerSafeElectronClient } from "./worker/client";
export interface LimitedElectronAPIs
extends Pick<ElectronAPIsType, "convertToJPEG" | "logToDisk"> {}
class WorkerSafeElectronServiceImpl implements LimitedElectronAPIs {
proxiedElectron:
| Comlink.Remote<WorkerSafeElectronClient>
| WorkerSafeElectronClient;
ready: Promise<any>;
constructor() {
this.ready = this.init();
}
private async init() {
if (inWorker()) {
const workerSafeElectronClient =
wrap<typeof WorkerSafeElectronClient>(self);
this.proxiedElectron = await new workerSafeElectronClient();
} else {
this.proxiedElectron = new WorkerSafeElectronClient();
}
}
async convertToJPEG(
inputFileData: Uint8Array,
filename: string,
): Promise<Uint8Array> {
await this.ready;
return this.proxiedElectron.convertToJPEG(inputFileData, filename);
}
async logToDisk(message: string) {
await this.ready;
return this.proxiedElectron.logToDisk(message);
}
}
export const WorkerSafeElectronService = new WorkerSafeElectronServiceImpl();

View file

@ -1,21 +0,0 @@
import ElectronAPIs from "@ente/shared/electron";
export interface ProxiedLimitedElectronAPIs {
convertToJPEG: (
inputFileData: Uint8Array,
filename: string,
) => Promise<Uint8Array>;
logToDisk: (message: string) => void;
}
export class WorkerSafeElectronClient implements ProxiedLimitedElectronAPIs {
async convertToJPEG(
inputFileData: Uint8Array,
filename: string,
): Promise<Uint8Array> {
return await ElectronAPIs.convertToJPEG(inputFileData, filename);
}
logToDisk(message: string) {
return ElectronAPIs.logToDisk(message);
}
}

View file

@ -1,8 +1,8 @@
import { inWorker, isDevBuild } from "@/next/env";
import { isDevBuild } from "@/next/env";
import { logError } from "@ente/shared/sentry";
import {
getData,
LS_KEYS,
getData,
removeData,
setData,
} from "@ente/shared/storage/localStorage";
@ -20,22 +20,13 @@ export interface Log {
logLine: string;
}
export function logWeb(logLine2: string) {
const logLine = `${logLine2}`;
console.log("logWeb", logLine);
export function logWeb(logLine: string) {
try {
const log: Log = { logLine, timestamp: Date.now() };
const logs = getLogs();
if (logs.length > MAX_LOG_LINES) {
logs.slice(logs.length - MAX_LOG_LINES);
}
console.log("inWorker", inWorker());
console.log("pushing", logLine);
console.log("length", logLine.length);
logs.push({
logLine: `length ${logLine.length}`,
timestamp: Date.now(),
});
logs.push(log);
setLogs(logs);
} catch (e) {

View file

@ -1,5 +1,6 @@
import { addLocalLog, logToDisk } from "@ente/shared/logging";
import { Remote, expose, wrap } from "comlink";
import ElectronAPIs from "../electron";
import { logError } from "../sentry";
export class ComlinkWorker<T extends new () => InstanceType<T>> {
@ -20,7 +21,6 @@ export class ComlinkWorker<T extends new () => InstanceType<T>> {
addLocalLog(() => `Initiated ${this.name}`);
const comlink = wrap<T>(this.worker);
this.remote = new comlink() as Promise<Remote<InstanceType<T>>>;
// expose(WorkerSafeElectronClient, this.worker);
expose(workerBridge, this.worker);
}
@ -43,6 +43,8 @@ export class ComlinkWorker<T extends new () => InstanceType<T>> {
*/
const workerBridge = {
logToDisk,
convertToJPEG: (inputFileData: Uint8Array, filename: string) =>
ElectronAPIs.convertToJPEG(inputFileData, filename),
};
export type WorkerBridge = typeof workerBridge;

View file

@ -9,4 +9,4 @@ import type { WorkerBridge } from "./comlinkWorker";
* this object will be transparently (but asynchrorously) relayed to the
* implementation of the {@link WorkerBridge} in `comlinkWorker.ts`.
*/
export const workerBridge = wrap<WorkerBridge>(self);
export const workerBridge = wrap<WorkerBridge>(globalThis);