1/** 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { WorkerType } from '../WorkFactory' 17import worker from '@ohos.worker'; 18import HiLog from '../../utils/HiLog'; 19import buffer from '@ohos.buffer' 20 21const TAG = 'WorkerWrapper' 22 23export class WorkerMessage { 24 request: string; 25 callBackId: number; 26 type?: WorkerType; 27 param?: any; 28} 29 30/* 31 * WorkerWrapper 32 * 33 * Processes sending tasks to workers and receiving work processing results. 34 */ 35export abstract class WorkerWrapper { 36 protected mWorker: worker.ThreadWorker = null; 37 private callBacks: Map<string, (result?: any) => void> = new Map(); 38 private requestIndex: number = 0; 39 40 constructor() { 41 this.initWorker(); 42 } 43 44 async initWorker() { 45 HiLog.i(TAG, `WorkerWrapper initWorker ${WorkerType[this.getWorkerType()]}`) 46 let initWorker = await new worker.ThreadWorker('entry/ets/workers/base/Worker.ts', { 47 name: WorkerType[this.getWorkerType()] 48 }); 49 let that = this; 50 initWorker.onexit = function (message) { 51 HiLog.w(TAG, 'onexit') 52 that.mWorker = null; 53 } 54 initWorker.onerror = function (e) { 55 HiLog.w(TAG, 'onerror:' + JSON.stringify(e)) 56 } 57 initWorker.onmessageerror = function (e) { 58 HiLog.w(TAG, 'onmessageerror:' + JSON.stringify(e)) 59 } 60 initWorker.onmessage = function (message) { 61 const buff = <ArrayBuffer> message.data; 62 const str = buffer.from(buff).toString(); 63 let data = <WorkerMessage> JSON.parse(str) 64 HiLog.i(TAG, `onmessage ${data.request}`) 65 const key = that.getCallBackKey(data); 66 if (that.callBacks.has(key)) { 67 HiLog.i(TAG, `onmessage notify result.`) 68 const callback = that.callBacks.get(key); 69 if (callback) { 70 callback(data.param); 71 } 72 that.callBacks.delete(key); 73 } 74 } 75 this.mWorker = initWorker; 76 HiLog.i(TAG, `WorkerWrapper initWorker end`) 77 } 78 79 public abstract getWorkerType(): WorkerType; 80 81 /** 82 * SendRequest to worker thread. 83 * 84 * @param {string} request the request worker to do 85 * @param {Object} requestData request param Data 86 * @param {Object} callBack Call back from worker 87 */ 88 public async sendRequest(request: string, requestData?: any, callBack?: (result?: any) => void) { 89 HiLog.i(TAG, 'sendRequest in ' + request) 90 if (this.mWorker) { 91 const message = { 92 request: request, 93 callBackId: this.requestIndex, 94 type: this.getWorkerType(), 95 param: requestData 96 } 97 if (callBack) { 98 this.callBacks.set(this.getCallBackKey(message), callBack); 99 } 100 this.mWorker?.postMessage(message); 101 HiLog.d(TAG, `${this.getWorkerType()} ${request} send succ!`); 102 this.requestIndex++; 103 } else { 104 HiLog.w(TAG, `${this.getWorkerType()} ${request} send fail, worker has been closed!`); 105 } 106 } 107 108 /** 109 * Close close worker thread. 110 */ 111 public close() { 112 HiLog.i(TAG, `${this.getWorkerType()} worker close!`); 113 if (this.mWorker != null) { 114 HiLog.i(TAG, 'this mWorker is right'); 115 this.mWorker.terminate(); 116 } 117 this.mWorker = null; 118 this.callBacks.clear(); 119 } 120 121 private getCallBackKey(message: WorkerMessage): string { 122 return message.request + message.callBackId; 123 } 124} 125 126export default WorkerWrapper;