• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()