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 16class PerfCallChainThread extends Worker { 17 busy: boolean = false; 18 taskMap: any = {}; 19 uuid(): string { 20 // @ts-ignore 21 return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11) 22 .replace(/[018]/g, (c: any) => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)); 23 } 24 25 queryFunc(name: string, args: any, handler: Function, action: string | null) { 26 this.busy = true; 27 let id = this.uuid(); 28 this.taskMap[id] = handler 29 let msg = { 30 id: id, 31 name: name, 32 action: action || "exec", 33 params: args, 34 } 35 this.postMessage(msg); 36 } 37 38} 39 40export class PerfCallChainPool { 41 maxThreadNumber: number = 0; 42 works: Array<PerfCallChainThread> = []; 43 44 close = async () => { 45 for (let i = 0; i < this.works.length; i++) { 46 let thread = this.works[i]; 47 thread.terminate(); 48 } 49 this.works.length = 0; 50 } 51 52 init = async () => { 53 await this.close(); 54 let thread = new PerfCallChainThread("trace/component/chart/PerfDataQuery.js", {type: "module"})//trace/component/chart/PerfDataQuery.js 55 thread!.onmessage = (event: MessageEvent) => { 56 thread.busy = false; 57 let fun = thread.taskMap[event.data.id]; 58 if (fun) { 59 fun(event.data.results); 60 } 61 Reflect.deleteProperty(thread.taskMap, event.data.id); 62 } 63 thread!.onmessageerror = e => { 64 } 65 thread!.onerror = e => { 66 } 67 thread!.busy = false; 68 this.works?.push(thread!); 69 } 70 71 submit(name: string, args: any, handler: Function, action: string | null) { 72 let noBusyThreads = this.works.filter(it => !it.busy); 73 let thread: PerfCallChainThread 74 if (noBusyThreads.length > 0) { //取第一个空闲的线程进行任务 75 thread = noBusyThreads[0]; 76 thread.queryFunc(name, args, handler, action) 77 } else { // 随机插入一个线程中 78 thread = this.works[Math.floor(Math.random() * this.works.length)] 79 thread.queryFunc(name, args, handler, action) 80 } 81 } 82 83} 84 85export const callChainsPool = new PerfCallChainPool()