diff --git a/src/services/HEICConverter.ts b/src/services/HEICConverter.ts deleted file mode 100644 index 152ce1cd6..000000000 --- a/src/services/HEICConverter.ts +++ /dev/null @@ -1,31 +0,0 @@ -import QueueProcessor from 'services/queueProcessor'; -import { ConvertWorker } from 'utils/comlink'; -import { CustomError } from 'utils/error'; -import { logError } from 'utils/sentry'; - -class HEICConverter { - private convertProcessor = new QueueProcessor(5); - private worker = null; - - async convert(fileBlob: Blob, format = 'JPEG'): Promise { - if (!this.worker) { - this.worker = await new ConvertWorker(); - } - const response = this.convertProcessor.queueUpRequest( - async () => await this.worker.convertHEIC(fileBlob, format) - ); - try { - return await response.promise; - } catch (e) { - if (e.message === CustomError.REQUEST_CANCELLED) { - // ignore - return null; - } else { - logError(e, 'heic conversion failed'); - throw e; - } - } - } -} - -export default new HEICConverter(); diff --git a/src/utils/file/convertHEIC.ts b/src/services/heicConverter/heicConverterClient.ts similarity index 74% rename from src/utils/file/convertHEIC.ts rename to src/services/heicConverter/heicConverterClient.ts index 28f066bde..18223aa88 100644 --- a/src/utils/file/convertHEIC.ts +++ b/src/services/heicConverter/heicConverterClient.ts @@ -1,10 +1,15 @@ import * as HeicConvert from 'heic-convert'; +const WAIT_TIME_IN_MICROSECONDS = 60 * 1000; + export async function convertHEIC( fileBlob: Blob, format: string ): Promise { const filedata = new Uint8Array(await fileBlob.arrayBuffer()); + setTimeout(() => { + throw Error('wait time exceeded'); + }, WAIT_TIME_IN_MICROSECONDS); const result = await HeicConvert({ buffer: filedata, format }); const convertedFileData = new Uint8Array(result); const convertedFileBlob = new Blob([convertedFileData]); diff --git a/src/services/heicConverter/heicConverterService.ts b/src/services/heicConverter/heicConverterService.ts new file mode 100644 index 000000000..0573796fc --- /dev/null +++ b/src/services/heicConverter/heicConverterService.ts @@ -0,0 +1,56 @@ +import QueueProcessor from 'services/queueProcessor'; +import { getDedicatedConvertWorker } from 'utils/comlink'; +import { CustomError } from 'utils/error'; +import { logError } from 'utils/sentry'; + +const WORKER_POOL_SIZE = 4; +const MAX_CONVERSION_IN_PARALLEL = 2; + +class HEICConverter { + private convertProcessor = new QueueProcessor( + MAX_CONVERSION_IN_PARALLEL + ); + private workerPool: any[]; + private ready: Promise; + + constructor() { + this.ready = this.init(); + } + async init() { + this.workerPool = []; + for (let i = 0; i < WORKER_POOL_SIZE; i++) { + const worker = getDedicatedConvertWorker().comlink; + if (!worker) { + return; + } + this.workerPool.push({ + id: i, + worker: await new worker(), + }); + } + } + async convert(fileBlob: Blob, format = 'PNG'): Promise { + await this.ready; + const response = this.convertProcessor.queueUpRequest(async () => { + const { id, worker } = this.workerPool.shift(); + try { + return await worker.convertHEIC(fileBlob, format); + } finally { + this.workerPool.push({ id, worker }); + } + }); + try { + return await response.promise; + } catch (e) { + if (e.message === CustomError.REQUEST_CANCELLED) { + // ignore + return null; + } else { + logError(e, 'heic conversion failed'); + throw e; + } + } + } +} + +export default new HEICConverter(); diff --git a/src/services/upload/thumbnailService.ts b/src/services/upload/thumbnailService.ts index 0e6221068..d10ffe166 100644 --- a/src/services/upload/thumbnailService.ts +++ b/src/services/upload/thumbnailService.ts @@ -7,7 +7,7 @@ import { convertToHumanReadable } from 'utils/billing'; import { isFileHEIC } from 'utils/file'; import { FileTypeInfo } from 'types/upload'; import { getUint8ArrayView } from '../readerService'; -import HEICConverter from 'services/HEICConverter'; +import HEICConverter from 'services/heicConverter/heicConverterService'; import { getFileNameSize, logUploadInfo } from 'utils/upload'; const MAX_THUMBNAIL_DIMENSION = 720; diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts index a5918a4c7..7397cf0b4 100644 --- a/src/utils/file/index.ts +++ b/src/utils/file/index.ts @@ -23,7 +23,7 @@ import { VISIBILITY_STATE, } from 'constants/file'; import PublicCollectionDownloadManager from 'services/publicCollectionDownloadManager'; -import HEICConverter from 'services/HEICConverter'; +import HEICConverter from 'services/heicConverter/heicConverterService'; import ffmpegService from 'services/ffmpeg/ffmpegService'; export function downloadAsFile(filename: string, content: string) { diff --git a/src/worker/convert.worker.js b/src/worker/convert.worker.js index a29a396fd..ee1a7ca55 100644 --- a/src/worker/convert.worker.js +++ b/src/worker/convert.worker.js @@ -1,9 +1,9 @@ import * as Comlink from 'comlink'; -import { convertHEIC } from 'utils/file/convertHEIC'; +import { convertHEIC } from 'services/heicConverter/heicConverterClient'; export class Convert { - async convertHEIC(format, file) { - return convertHEIC(format, file); + async convertHEIC(fileBlob, format) { + return convertHEIC(fileBlob, format); } }