• 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
16import { DbPool } from './SqlLite';
17class ConvertThread {
18  isCancelled: boolean = false;
19  id: number = -1;
20  taskMap: any = {};
21  name: string | undefined;
22  worker?: Worker;
23  busy: boolean = false;
24  constructor(worker: Worker) {
25    this.worker = worker;
26  }
27  uuid(): string {
28    // @ts-ignore
29    return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) =>
30      (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
31    );
32  }
33
34  getConvertData(handler: (status: boolean, msg: string, results: Blob) => void) {
35    this.busy = true;
36    let id = this.uuid();
37    this.taskMap[id] = (res: any) => {
38      DbPool.sharedBuffer = res.buffer;
39      handler(res.status, res.msg, res.results);
40    };
41    caches.match(DbPool.fileCacheKey).then((resData) => {
42      if (resData) {
43        resData.arrayBuffer().then((buffer) => {
44          this.worker!.postMessage(
45            {
46              id: id,
47              action: 'getConvertData',
48              buffer: buffer!,
49            },
50            [buffer!]
51          );
52        });
53      }
54    });
55  }
56}
57
58class ConvertPool {
59  maxThreadNumber: number = 0;
60  works: Array<ConvertThread> = [];
61  progress: Function | undefined | null;
62  static data: Array<string> = [];
63  num = Math.floor(Math.random() * 10 + 1) + 20;
64  init = async (type: string) => {
65    // server
66    await this.close();
67    if (type === 'convert') {
68      this.maxThreadNumber = 1;
69    }
70    for (let i = 0; i < this.maxThreadNumber; i++) {
71      let thread: ConvertThread;
72      if (type === 'convert') {
73        thread = new ConvertThread(new Worker(new URL('./ConvertTraceWorker', import.meta.url)));
74      }
75      thread!.worker!.onmessage = (event: MessageEvent) => {
76        thread.busy = false;
77        ConvertPool.data = event.data.results;
78        if (Reflect.has(thread.taskMap, event.data.id)) {
79          if (event.data.results) {
80            let fun = thread.taskMap[event.data.id];
81            if (fun) {
82              fun(event.data);
83            }
84            Reflect.deleteProperty(thread.taskMap, event.data.id);
85          } else {
86            let fun = thread.taskMap[event.data.id];
87            if (fun) {
88              fun([]);
89            }
90            Reflect.deleteProperty(thread.taskMap, event.data.id);
91          }
92        }
93      };
94      thread!.worker!.onmessageerror = (e) => {};
95      thread!.worker!.onerror = (e) => {};
96      thread!.id = i;
97      thread!.busy = false;
98      this.works?.push(thread!);
99    }
100  };
101
102  clearCache = () => {
103    for (let i = 0; i < this.works.length; i++) {
104      let thread = this.works[i];
105      thread.getConvertData(() => {});
106    }
107  };
108
109  close = () => {
110    for (let i = 0; i < this.works.length; i++) {
111      let thread = this.works[i];
112      thread.worker!.terminate();
113    }
114    this.works.length = 0;
115  };
116
117  // @ts-ignore
118  submitWithName(
119    name: string,
120    handler: (status: boolean, msg: string, results: Blob) => void
121  ): ConvertThread | undefined {
122    let noBusyThreads = this.works;
123    let thread: ConvertThread | undefined;
124    if (noBusyThreads.length > 0) {
125      //取第一个空闲的线程进行任务
126      thread = noBusyThreads[0];
127      thread!.getConvertData(handler);
128    }
129    return thread;
130  }
131
132  isIdle() {
133    return this.works.every((it) => !it.busy);
134  }
135}
136
137export const convertPool = new ConvertPool();
138