Drop smack/capability main thread with standalone model
[platform/framework/web/wrtjs.git] / wrt_app / common / service_manager.ts
1 import { Worker, isMainThread } from 'worker_threads';
2 import { wrt } from '../browser/wrt';
3
4 interface WorkerMap {
5   [id: string]: any;
6 }
7 let workers: WorkerMap = {};
8 let runner: any;
9
10 Object.defineProperty(global, 'serviceType', {
11   value: wrt.getServiceModel(),
12   writable: false
13 });
14
15 function createWorker(id: string, startService: string, filename: string) {
16   if (workers[id])
17     return;
18
19   workers[id] = new Worker(startService, {
20     workerData: {
21       id,
22       filename
23     }
24   });
25   workers[id].on('message', (message: string) => {
26     if (message === 'will-terminate') {
27       workers[id].terminate();
28     }
29   });
30   workers[id].on('exit', (code: number) => {
31     delete workers[id];
32     let runningServices = Object.keys(workers).length;
33     console.log(`exit code(${code}), remain services(${runningServices})`);
34   });
35 }
36
37 function terminateWorker(id: string, delay: number) {
38   if (!workers[id]) {
39     console.log(`This worker is already terminated. ${id}`);
40     return;
41   }
42   console.log(`${id} will shutdown after ${delay}ms`);
43   workers[id].postMessage({ type: 'stop', delay });
44 }
45
46 export function startService(id: string, filename: string) {
47   console.log(`startService - ${id}`);
48   if (global['serviceType'] === 'STANDALONE') {
49     let ids = id.split(':');
50     let serviceId = ids[0];
51     let packageId = serviceId.split('.')[0];
52     wrt.security?.dropThreadPrivilege(packageId, serviceId);
53   }
54   let startService = `${__dirname}/service_runner.js`;
55   createWorker(id, startService, filename);
56 }
57
58 export function stopService(id: string) {
59   console.log(`stopService - ${id}`);
60   terminateWorker(id, 500);
61 }
62
63 export function handleBuiltinService(serviceId: string, serviceName: string) {
64   if (!serviceName) {
65     return;
66   }
67   let need_stop = (serviceName.substr(0, 5) === 'stop_');
68   if (need_stop) {
69     console.log(`${serviceName} will be terminated.`);
70     workers[serviceId].terminate();
71   } else {
72     console.log(`Builtin service is ${serviceName}`);
73     let startService = `${__dirname}/../service/builtins/${serviceName}.js`;
74     createWorker(serviceId, startService, '');
75   }
76 }