mirror of
https://github.com/ente-io/ente.git
synced 2025-08-08 15:30:40 +00:00
fixing logging in workers WIP 2
This commit is contained in:
parent
a96ad6dfa2
commit
da9a704094
@ -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();
|
|
@ -1,3 +1,4 @@
|
|||||||
|
import ElectronAPIs from "@ente/shared/electron";
|
||||||
import { CustomError } from "@ente/shared/error";
|
import { CustomError } from "@ente/shared/error";
|
||||||
import { addLogLine } from "@ente/shared/logging";
|
import { addLogLine } from "@ente/shared/logging";
|
||||||
import { getFileNameSize } from "@ente/shared/logging/web";
|
import { getFileNameSize } from "@ente/shared/logging/web";
|
||||||
@ -8,7 +9,6 @@ import { BLACK_THUMBNAIL_BASE64 } from "constants/upload";
|
|||||||
import isElectron from "is-electron";
|
import isElectron from "is-electron";
|
||||||
import * as FFmpegService from "services/ffmpeg/ffmpegService";
|
import * as FFmpegService from "services/ffmpeg/ffmpegService";
|
||||||
import HeicConversionService from "services/heicConversionService";
|
import HeicConversionService from "services/heicConversionService";
|
||||||
import imageProcessor from "services/imageProcessor";
|
|
||||||
import { ElectronFile, FileTypeInfo } from "types/upload";
|
import { ElectronFile, FileTypeInfo } from "types/upload";
|
||||||
import { isFileHEIC } from "utils/file";
|
import { isFileHEIC } from "utils/file";
|
||||||
import { getUint8ArrayView } from "../readerService";
|
import { getUint8ArrayView } from "../readerService";
|
||||||
@ -86,7 +86,7 @@ async function generateImageThumbnail(
|
|||||||
) {
|
) {
|
||||||
if (isElectron()) {
|
if (isElectron()) {
|
||||||
try {
|
try {
|
||||||
return await imageProcessor.generateImageThumbnail(
|
return await generateImageThumbnailInElectron(
|
||||||
file,
|
file,
|
||||||
MAX_THUMBNAIL_DIMENSION,
|
MAX_THUMBNAIL_DIMENSION,
|
||||||
MAX_THUMBNAIL_SIZE,
|
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(
|
export async function generateImageThumbnailUsingCanvas(
|
||||||
file: File | ElectronFile,
|
file: File | ElectronFile,
|
||||||
fileTypeInfo: FileTypeInfo,
|
fileTypeInfo: FileTypeInfo,
|
||||||
|
@ -53,8 +53,8 @@ import {
|
|||||||
import { FileTypeInfo } from "types/upload";
|
import { FileTypeInfo } from "types/upload";
|
||||||
|
|
||||||
import { default as ElectronAPIs } from "@ente/shared/electron";
|
import { default as ElectronAPIs } from "@ente/shared/electron";
|
||||||
|
import { workerBridge } from "@ente/shared/worker/worker-bridge";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import imageProcessor from "services/imageProcessor";
|
|
||||||
import { getFileExportPath, getUniqueFileExportName } from "utils/export";
|
import { getFileExportPath, getUniqueFileExportName } from "utils/export";
|
||||||
|
|
||||||
const WAIT_TIME_IMAGE_CONVERSION = 30 * 1000;
|
const WAIT_TIME_IMAGE_CONVERSION = 30 * 1000;
|
||||||
@ -452,8 +452,7 @@ export async function getRenderableImage(fileName: string, imageBlob: Blob) {
|
|||||||
imageBlob.size,
|
imageBlob.size,
|
||||||
)}`,
|
)}`,
|
||||||
);
|
);
|
||||||
throw new Error("bypass");
|
convertedImageBlob = await convertToJPEGInElectron(
|
||||||
convertedImageBlob = await imageProcessor.convertToJPEG(
|
|
||||||
imageBlob,
|
imageBlob,
|
||||||
fileName,
|
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) {
|
export function isFileHEIC(exactType: string) {
|
||||||
return (
|
return (
|
||||||
exactType.toLowerCase().endsWith(TYPE_HEIC) ||
|
exactType.toLowerCase().endsWith(TYPE_HEIC) ||
|
||||||
|
@ -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();
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,8 @@
|
|||||||
import { inWorker, isDevBuild } from "@/next/env";
|
import { isDevBuild } from "@/next/env";
|
||||||
import { logError } from "@ente/shared/sentry";
|
import { logError } from "@ente/shared/sentry";
|
||||||
import {
|
import {
|
||||||
getData,
|
|
||||||
LS_KEYS,
|
LS_KEYS,
|
||||||
|
getData,
|
||||||
removeData,
|
removeData,
|
||||||
setData,
|
setData,
|
||||||
} from "@ente/shared/storage/localStorage";
|
} from "@ente/shared/storage/localStorage";
|
||||||
@ -20,22 +20,13 @@ export interface Log {
|
|||||||
logLine: string;
|
logLine: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logWeb(logLine2: string) {
|
export function logWeb(logLine: string) {
|
||||||
const logLine = `${logLine2}`;
|
|
||||||
console.log("logWeb", logLine);
|
|
||||||
try {
|
try {
|
||||||
const log: Log = { logLine, timestamp: Date.now() };
|
const log: Log = { logLine, timestamp: Date.now() };
|
||||||
const logs = getLogs();
|
const logs = getLogs();
|
||||||
if (logs.length > MAX_LOG_LINES) {
|
if (logs.length > MAX_LOG_LINES) {
|
||||||
logs.slice(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);
|
logs.push(log);
|
||||||
setLogs(logs);
|
setLogs(logs);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { addLocalLog, logToDisk } from "@ente/shared/logging";
|
import { addLocalLog, logToDisk } from "@ente/shared/logging";
|
||||||
import { Remote, expose, wrap } from "comlink";
|
import { Remote, expose, wrap } from "comlink";
|
||||||
|
import ElectronAPIs from "../electron";
|
||||||
import { logError } from "../sentry";
|
import { logError } from "../sentry";
|
||||||
|
|
||||||
export class ComlinkWorker<T extends new () => InstanceType<T>> {
|
export class ComlinkWorker<T extends new () => InstanceType<T>> {
|
||||||
@ -20,7 +21,6 @@ export class ComlinkWorker<T extends new () => InstanceType<T>> {
|
|||||||
addLocalLog(() => `Initiated ${this.name}`);
|
addLocalLog(() => `Initiated ${this.name}`);
|
||||||
const comlink = wrap<T>(this.worker);
|
const comlink = wrap<T>(this.worker);
|
||||||
this.remote = new comlink() as Promise<Remote<InstanceType<T>>>;
|
this.remote = new comlink() as Promise<Remote<InstanceType<T>>>;
|
||||||
// expose(WorkerSafeElectronClient, this.worker);
|
|
||||||
expose(workerBridge, this.worker);
|
expose(workerBridge, this.worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +43,8 @@ export class ComlinkWorker<T extends new () => InstanceType<T>> {
|
|||||||
*/
|
*/
|
||||||
const workerBridge = {
|
const workerBridge = {
|
||||||
logToDisk,
|
logToDisk,
|
||||||
|
convertToJPEG: (inputFileData: Uint8Array, filename: string) =>
|
||||||
|
ElectronAPIs.convertToJPEG(inputFileData, filename),
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WorkerBridge = typeof workerBridge;
|
export type WorkerBridge = typeof workerBridge;
|
||||||
|
@ -9,4 +9,4 @@ import type { WorkerBridge } from "./comlinkWorker";
|
|||||||
* this object will be transparently (but asynchrorously) relayed to the
|
* this object will be transparently (but asynchrorously) relayed to the
|
||||||
* implementation of the {@link WorkerBridge} in `comlinkWorker.ts`.
|
* implementation of the {@link WorkerBridge} in `comlinkWorker.ts`.
|
||||||
*/
|
*/
|
||||||
export const workerBridge = wrap<WorkerBridge>(self);
|
export const workerBridge = wrap<WorkerBridge>(globalThis);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user