alemonjs 2.1.3 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README_CONFIG.md +1 -1
- package/lib/process/module.js +64 -46
- package/lib/process/platform.d.ts +1 -1
- package/lib/process/platform.js +126 -85
- package/package.json +1 -1
package/README_CONFIG.md
CHANGED
package/lib/process/module.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import childProcess from 'child_process';
|
|
2
2
|
import { ResultCode } from '../core/variable.js';
|
|
3
|
-
import '
|
|
4
|
-
import 'path';
|
|
5
|
-
import 'yaml';
|
|
3
|
+
import { getConfigValue } from '../core/config.js';
|
|
6
4
|
import '../core/utils.js';
|
|
7
5
|
import module from 'module';
|
|
8
6
|
|
|
@@ -10,95 +8,115 @@ const initRequire = () => { };
|
|
|
10
8
|
initRequire.resolve = () => '';
|
|
11
9
|
const require = module?.createRequire?.(import.meta.url) ?? initRequire;
|
|
12
10
|
function startModuleAdapter() {
|
|
11
|
+
const values = getConfigValue();
|
|
12
|
+
const pro = values?.process ?? {};
|
|
13
13
|
let modulePath = '';
|
|
14
|
+
const CONFIG = {
|
|
15
|
+
RESTART_DELAY: pro?.restart_delay ?? 3000,
|
|
16
|
+
FORK_TIMEOUT: pro?.fork_timeout ?? 6000
|
|
17
|
+
};
|
|
14
18
|
try {
|
|
15
19
|
modulePath = require.resolve('../client.js');
|
|
16
20
|
}
|
|
17
|
-
catch (
|
|
21
|
+
catch (error) {
|
|
18
22
|
logger?.warn?.({
|
|
19
23
|
code: ResultCode.Fail,
|
|
20
|
-
message: '
|
|
21
|
-
data:
|
|
24
|
+
message: '模块加载进程启动失败',
|
|
25
|
+
data: error
|
|
22
26
|
});
|
|
23
27
|
return;
|
|
24
28
|
}
|
|
25
29
|
const startByFork = () => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
const manager = {
|
|
31
|
+
restarted: false,
|
|
32
|
+
ready: false
|
|
33
|
+
};
|
|
34
|
+
const cleanup = () => {
|
|
35
|
+
if (manager.timer) {
|
|
36
|
+
clearTimeout(manager.timer);
|
|
37
|
+
manager.timer = undefined;
|
|
38
|
+
}
|
|
39
|
+
if (manager.child) {
|
|
40
|
+
manager.child.removeAllListeners();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
29
43
|
const restart = () => {
|
|
30
|
-
if (restarted) {
|
|
44
|
+
if (manager.restarted) {
|
|
31
45
|
return;
|
|
32
46
|
}
|
|
33
|
-
restarted = true;
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
manager.restarted = true;
|
|
48
|
+
cleanup();
|
|
49
|
+
setTimeout(() => {
|
|
50
|
+
startByFork();
|
|
51
|
+
}, CONFIG.RESTART_DELAY);
|
|
52
|
+
};
|
|
53
|
+
const checkTimeout = () => {
|
|
54
|
+
if (!manager.ready) {
|
|
55
|
+
logger?.error?.({
|
|
56
|
+
code: ResultCode.Fail,
|
|
57
|
+
message: '模块加载未及时响应(未发送 ready 消息)',
|
|
58
|
+
data: null
|
|
59
|
+
});
|
|
36
60
|
try {
|
|
37
|
-
child
|
|
61
|
+
manager.child?.kill();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
38
64
|
}
|
|
39
|
-
catch { }
|
|
40
65
|
}
|
|
41
|
-
setTimeout(() => {
|
|
42
|
-
startByFork();
|
|
43
|
-
}, 3000);
|
|
44
66
|
};
|
|
45
67
|
try {
|
|
46
|
-
child = childProcess.fork(modulePath, [], {
|
|
68
|
+
manager.child = childProcess.fork(modulePath, [], {
|
|
47
69
|
execArgv: process.execArgv
|
|
48
70
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
code: ResultCode.Fail,
|
|
53
|
-
message: '模块加载未及时响应(未发送 ready 消息)',
|
|
54
|
-
data: null
|
|
55
|
-
});
|
|
56
|
-
try {
|
|
57
|
-
child?.kill();
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
const timer = setTimeout(() => void checkTimeout(), 2000);
|
|
64
|
-
child.on('exit', (code, signal) => {
|
|
65
|
-
clearTimeout(timer);
|
|
71
|
+
manager.timer = setTimeout(checkTimeout, CONFIG.FORK_TIMEOUT);
|
|
72
|
+
manager.child.on('exit', (code, signal) => {
|
|
73
|
+
cleanup();
|
|
66
74
|
logger?.warn?.({
|
|
67
75
|
code: ResultCode.Fail,
|
|
68
|
-
message: `模块加载子进程已退出,code=${code}, signal=${signal}
|
|
76
|
+
message: `模块加载子进程已退出,code=${code}, signal=${signal},${CONFIG.RESTART_DELAY / 1000}秒后自动重启`,
|
|
69
77
|
data: null
|
|
70
78
|
});
|
|
71
79
|
restart();
|
|
72
80
|
});
|
|
73
|
-
child.on('message',
|
|
81
|
+
manager.child.on('message', (message) => {
|
|
74
82
|
try {
|
|
75
|
-
const data = typeof
|
|
83
|
+
const data = typeof message === 'string' ? JSON.parse(message) : message;
|
|
76
84
|
if (data?.type === 'ready') {
|
|
77
|
-
ready = true;
|
|
78
|
-
|
|
85
|
+
manager.ready = true;
|
|
86
|
+
cleanup();
|
|
79
87
|
logger?.debug?.({
|
|
80
88
|
code: ResultCode.Ok,
|
|
81
89
|
message: '模块加载已就绪(子进程 fork 模式)',
|
|
82
90
|
data: null
|
|
83
91
|
});
|
|
84
|
-
child?.send?.({ type: 'start' });
|
|
92
|
+
manager.child?.send?.({ type: 'start' });
|
|
85
93
|
}
|
|
86
94
|
}
|
|
87
|
-
catch (
|
|
95
|
+
catch (error) {
|
|
88
96
|
logger?.error?.({
|
|
89
97
|
code: ResultCode.Fail,
|
|
90
98
|
message: '模块加载进程通信数据格式错误',
|
|
91
|
-
data:
|
|
99
|
+
data: error
|
|
92
100
|
});
|
|
93
101
|
}
|
|
94
102
|
});
|
|
103
|
+
manager.child.on('error', (error) => {
|
|
104
|
+
logger?.error?.({
|
|
105
|
+
code: ResultCode.Fail,
|
|
106
|
+
message: '模块加载子进程发生错误',
|
|
107
|
+
data: error
|
|
108
|
+
});
|
|
109
|
+
});
|
|
95
110
|
}
|
|
96
|
-
catch (
|
|
111
|
+
catch (error) {
|
|
97
112
|
logger?.warn?.({
|
|
98
113
|
code: ResultCode.Fail,
|
|
99
114
|
message: 'fork 启动模块加载失败',
|
|
100
|
-
data:
|
|
115
|
+
data: error
|
|
101
116
|
});
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
startByFork();
|
|
119
|
+
}, CONFIG.RESTART_DELAY);
|
|
102
120
|
}
|
|
103
121
|
};
|
|
104
122
|
startByFork();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function startPlatformAdapterWithFallback(): void
|
|
1
|
+
export declare function startPlatformAdapterWithFallback(): Promise<void>;
|
package/lib/process/platform.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import childProcess from 'child_process';
|
|
2
2
|
import { ResultCode } from '../core/variable.js';
|
|
3
|
-
import '
|
|
4
|
-
import 'path';
|
|
5
|
-
import 'yaml';
|
|
3
|
+
import { getConfigValue } from '../core/config.js';
|
|
6
4
|
import '../core/utils.js';
|
|
7
5
|
import module from 'module';
|
|
8
6
|
|
|
@@ -10,138 +8,181 @@ const initRequire = () => { };
|
|
|
10
8
|
initRequire.resolve = () => '';
|
|
11
9
|
const require = module?.createRequire?.(import.meta.url) ?? initRequire;
|
|
12
10
|
function startPlatformAdapterWithFallback() {
|
|
11
|
+
const values = getConfigValue();
|
|
12
|
+
const pro = values?.process ?? {};
|
|
13
|
+
const CONFIG = {
|
|
14
|
+
RESTART_DELAY: pro?.restart_delay ?? 3000,
|
|
15
|
+
FORK_TIMEOUT: pro?.fork_timeout ?? 6000,
|
|
16
|
+
FORK_RESTART_DELAY: pro?.fork_restart_delay ?? 5000
|
|
17
|
+
};
|
|
18
|
+
const platformPath = process.env.platform;
|
|
19
|
+
if (!platformPath) {
|
|
20
|
+
logger?.error?.({
|
|
21
|
+
code: ResultCode.Fail,
|
|
22
|
+
message: '未配置平台连接路径',
|
|
23
|
+
data: null
|
|
24
|
+
});
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
13
27
|
let modulePath = '';
|
|
28
|
+
let isForkFailed = false;
|
|
29
|
+
let imported = false;
|
|
14
30
|
try {
|
|
15
|
-
modulePath = require.resolve(
|
|
31
|
+
modulePath = require.resolve(platformPath);
|
|
16
32
|
}
|
|
17
33
|
catch {
|
|
18
|
-
void import(process.env.platform).then(res => res?.default());
|
|
19
34
|
logger?.warn?.({
|
|
20
35
|
code: ResultCode.Fail,
|
|
21
|
-
message: '平台连接包未支持 require
|
|
36
|
+
message: '平台连接包未支持 require',
|
|
22
37
|
data: null
|
|
23
38
|
});
|
|
24
39
|
return;
|
|
25
40
|
}
|
|
26
|
-
|
|
41
|
+
const startByImport = async () => {
|
|
42
|
+
if (imported) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
imported = true;
|
|
46
|
+
isForkFailed = true;
|
|
47
|
+
try {
|
|
48
|
+
const importPath = modulePath.startsWith('file://') ? modulePath : `file://${modulePath}`;
|
|
49
|
+
const mod = await import(importPath);
|
|
50
|
+
if (typeof mod.default === 'function') {
|
|
51
|
+
await mod.default();
|
|
52
|
+
logger?.debug?.({
|
|
53
|
+
code: ResultCode.Ok,
|
|
54
|
+
message: '通过 import 启动平台连接完成',
|
|
55
|
+
data: null
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
logger?.warn?.({
|
|
60
|
+
code: ResultCode.Fail,
|
|
61
|
+
message: '通过 import 启动平台连接,但未找到默认导出函数',
|
|
62
|
+
data: null
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
logger?.error?.({
|
|
68
|
+
code: ResultCode.Fail,
|
|
69
|
+
message: 'import 启动平台连接失败',
|
|
70
|
+
data: error
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
};
|
|
27
74
|
const startByFork = () => {
|
|
28
75
|
if (imported) {
|
|
29
76
|
return;
|
|
30
77
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
78
|
+
if (isForkFailed) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const manager = {
|
|
82
|
+
restarted: false,
|
|
83
|
+
ready: false,
|
|
84
|
+
isKilling: false
|
|
85
|
+
};
|
|
86
|
+
const cleanup = () => {
|
|
87
|
+
if (manager.timer) {
|
|
88
|
+
clearTimeout(manager.timer);
|
|
89
|
+
manager.timer = undefined;
|
|
90
|
+
}
|
|
91
|
+
if (manager.child) {
|
|
92
|
+
manager.child.removeAllListeners();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
34
95
|
const restart = () => {
|
|
35
|
-
if (restarted || imported) {
|
|
96
|
+
if (manager.restarted || imported) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
manager.restarted = true;
|
|
100
|
+
cleanup();
|
|
101
|
+
setTimeout(() => {
|
|
102
|
+
if (!imported && !isForkFailed) {
|
|
103
|
+
startByFork();
|
|
104
|
+
}
|
|
105
|
+
}, CONFIG.RESTART_DELAY);
|
|
106
|
+
};
|
|
107
|
+
const handleForkFailure = (error) => {
|
|
108
|
+
if (imported) {
|
|
36
109
|
return;
|
|
37
110
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
111
|
+
isForkFailed = true;
|
|
112
|
+
cleanup();
|
|
113
|
+
logger?.warn?.({
|
|
114
|
+
code: ResultCode.Fail,
|
|
115
|
+
message: 'fork 启动平台连接失败,将尝试 import 加载',
|
|
116
|
+
data: error
|
|
117
|
+
});
|
|
118
|
+
void startByImport();
|
|
119
|
+
};
|
|
120
|
+
const checkTimeout = () => {
|
|
121
|
+
if (!manager.ready && !imported) {
|
|
122
|
+
logger?.warn?.({
|
|
123
|
+
code: ResultCode.Fail,
|
|
124
|
+
message: '平台连接未及时响应(未发送 ready 消息),降级为 import 加载, 请升级对应的平台连接包以提高进程稳定性',
|
|
125
|
+
data: null
|
|
126
|
+
});
|
|
127
|
+
manager.isKilling = true;
|
|
41
128
|
try {
|
|
42
|
-
child
|
|
129
|
+
manager.child?.kill();
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
43
132
|
}
|
|
44
|
-
|
|
133
|
+
handleForkFailure();
|
|
45
134
|
}
|
|
46
|
-
setTimeout(() => {
|
|
47
|
-
startByFork();
|
|
48
|
-
}, 3000);
|
|
49
135
|
};
|
|
50
136
|
try {
|
|
51
|
-
child = childProcess.fork(modulePath, [], {
|
|
137
|
+
manager.child = childProcess.fork(modulePath, [], {
|
|
52
138
|
execArgv: process.execArgv
|
|
53
139
|
});
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
data: null
|
|
60
|
-
});
|
|
61
|
-
try {
|
|
62
|
-
child?.kill();
|
|
63
|
-
}
|
|
64
|
-
catch { }
|
|
65
|
-
await startByImport();
|
|
140
|
+
manager.timer = setTimeout(checkTimeout, CONFIG.FORK_TIMEOUT);
|
|
141
|
+
manager.child.on('exit', (code, signal) => {
|
|
142
|
+
cleanup();
|
|
143
|
+
if (manager.isKilling) {
|
|
144
|
+
return;
|
|
66
145
|
}
|
|
67
|
-
};
|
|
68
|
-
const timer = setTimeout(() => void checkTimeout(), 2000);
|
|
69
|
-
child.on('exit', (code, signal) => {
|
|
70
|
-
clearTimeout(timer);
|
|
71
146
|
if (!imported) {
|
|
72
147
|
logger?.warn?.({
|
|
73
148
|
code: ResultCode.Fail,
|
|
74
|
-
message: `平台连接子进程已退出,code=${code}, signal=${signal}
|
|
149
|
+
message: `平台连接子进程已退出,code=${code}, signal=${signal},${CONFIG.FORK_RESTART_DELAY / 1000}秒后自动重启`,
|
|
75
150
|
data: null
|
|
76
151
|
});
|
|
77
152
|
restart();
|
|
78
153
|
}
|
|
79
154
|
});
|
|
80
|
-
child.on('message',
|
|
155
|
+
manager.child.on('message', (message) => {
|
|
81
156
|
try {
|
|
82
|
-
const data = typeof
|
|
157
|
+
const data = typeof message === 'string' ? JSON.parse(message) : message;
|
|
83
158
|
if (data?.type === 'ready') {
|
|
84
|
-
ready = true;
|
|
85
|
-
|
|
159
|
+
manager.ready = true;
|
|
160
|
+
if (manager.timer) {
|
|
161
|
+
clearTimeout(manager.timer);
|
|
162
|
+
manager.timer = undefined;
|
|
163
|
+
}
|
|
86
164
|
logger?.debug?.({
|
|
87
165
|
code: ResultCode.Ok,
|
|
88
166
|
message: '平台连接已就绪(子进程 fork 模式)',
|
|
89
167
|
data: null
|
|
90
168
|
});
|
|
91
|
-
child?.send?.({ type: 'start' });
|
|
169
|
+
manager.child?.send?.({ type: 'start' });
|
|
92
170
|
}
|
|
93
171
|
}
|
|
94
|
-
catch (
|
|
172
|
+
catch (error) {
|
|
95
173
|
logger?.error?.({
|
|
96
174
|
code: ResultCode.Fail,
|
|
97
175
|
message: '平台连接进程通信数据格式错误',
|
|
98
|
-
data:
|
|
176
|
+
data: error
|
|
99
177
|
});
|
|
100
178
|
}
|
|
101
179
|
});
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
logger?.warn?.({
|
|
105
|
-
code: ResultCode.Fail,
|
|
106
|
-
message: 'fork 启动平台连接失败,将尝试 import 加载',
|
|
107
|
-
data: err
|
|
180
|
+
manager.child.on('error', (error) => {
|
|
181
|
+
handleForkFailure(error);
|
|
108
182
|
});
|
|
109
|
-
void startByImport();
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
const startByImport = async () => {
|
|
113
|
-
if (imported) {
|
|
114
|
-
return;
|
|
115
183
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
let importPath = modulePath;
|
|
119
|
-
if (!importPath.startsWith('file://')) {
|
|
120
|
-
importPath = 'file://' + importPath;
|
|
121
|
-
}
|
|
122
|
-
const mod = await import(importPath);
|
|
123
|
-
if (typeof mod.default === 'function') {
|
|
124
|
-
await mod.default();
|
|
125
|
-
logger?.debug?.({
|
|
126
|
-
code: ResultCode.Ok,
|
|
127
|
-
message: '通过 import 启动平台连接完成',
|
|
128
|
-
data: null
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
logger?.warn?.({
|
|
133
|
-
code: ResultCode.Fail,
|
|
134
|
-
message: '通过 import 启动平台连接,但未找到默认导出函数',
|
|
135
|
-
data: null
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
catch (err) {
|
|
140
|
-
logger?.error?.({
|
|
141
|
-
code: ResultCode.Fail,
|
|
142
|
-
message: 'import 启动平台连接失败',
|
|
143
|
-
data: err
|
|
144
|
-
});
|
|
184
|
+
catch (error) {
|
|
185
|
+
handleForkFailure(error);
|
|
145
186
|
}
|
|
146
187
|
};
|
|
147
188
|
startByFork();
|