* Decorator that manages the (re)starting of the worker and aborting existing jobs. Not all * processing jobs require a worker (e.g. the main thread canvas encodes), use the needsWorker * option to control this.
(options: ProcessingJobOptions = {})
| 48 | * option to control this. |
| 49 | */ |
| 50 | private static _processingJob(options: ProcessingJobOptions = {}) { |
| 51 | const { needsWorker = false } = options; |
| 52 | |
| 53 | return (target: Processor, propertyKey: string, descriptor: PropertyDescriptor): void => { |
| 54 | const processingFunc = descriptor.value; |
| 55 | |
| 56 | descriptor.value = async function (this: Processor, ...args: any[]) { |
| 57 | this._latestJobId += 1; |
| 58 | const jobId = this._latestJobId; |
| 59 | this.abortCurrent(); |
| 60 | |
| 61 | if (needsWorker) self.clearTimeout(this._workerTimeoutId); |
| 62 | |
| 63 | if (!this._worker && needsWorker) { |
| 64 | // worker-loader does magic here. |
| 65 | // @ts-ignore - Typescript doesn't know about the 2nd param to new Worker, and the |
| 66 | // definition can't be overwritten. |
| 67 | this._worker = new Worker( |
| 68 | './processor-worker', |
| 69 | { name: 'processor-worker', type: 'module' }, |
| 70 | ) as Worker; |
| 71 | // Need to do some TypeScript trickery to make the type match. |
| 72 | this._workerApi = proxy(this._worker) as any as ProcessorWorkerApi; |
| 73 | } |
| 74 | |
| 75 | this._busy = true; |
| 76 | |
| 77 | const returnVal = Promise.race([ |
| 78 | processingFunc.call(this, ...args), |
| 79 | new Promise((_, reject) => { this._abortRejector = reject; }), |
| 80 | ]); |
| 81 | |
| 82 | // Wait for the operation to settle. |
| 83 | await returnVal.catch(() => {}); |
| 84 | |
| 85 | // If no other jobs are happening, cleanup. |
| 86 | if (jobId === this._latestJobId) this._jobCleanup(); |
| 87 | |
| 88 | return returnVal; |
| 89 | }; |
| 90 | }; |
| 91 | } |
| 92 | |
| 93 | private _jobCleanup(): void { |
| 94 | this._busy = false; |
no test coverage detected