alemonjs 2.1.89 → 2.1.91
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/bin/README.md +8 -1
- package/bin/alemonc.js +1 -2
- package/bin/publish.js +58 -23
- package/lib/application/runtime/cbp/connects/client.js +11 -1
- package/lib/application/runtime/client-runtime.d.ts +2 -0
- package/lib/application/runtime/client-runtime.js +14 -36
- package/lib/application/runtime/load-modules/load.d.ts +2 -2
- package/lib/application/runtime/load-modules/load.js +8 -8
- package/lib/application/runtime/load-modules/loadChild.d.ts +1 -1
- package/lib/application/runtime/load-modules/loadChild.js +3 -3
- package/lib/client.d.ts +1 -1
- package/lib/client.js +91 -1
- package/lib/core/index.d.ts +3 -0
- package/lib/core/index.js +2 -0
- package/lib/core/process/index.d.ts +1 -0
- package/lib/core/process/index.js +2 -2
- package/lib/core/process/ipc-bridge.js +12 -0
- package/lib/core/process/module.d.ts +3 -0
- package/lib/core/process/module.js +340 -101
- package/lib/core/process/platform.d.ts +3 -0
- package/lib/core/process/platform.js +393 -165
- package/lib/core/process/types.d.ts +22 -0
- package/lib/core/process/types.js +1 -0
- package/lib/global.d.ts +3 -0
- package/lib/index.js +2 -0
- package/lib/main.d.ts +1 -0
- package/lib/main.js +2 -0
- package/lib/platform/cbp-platform.js +11 -1
- package/lib/platform/define-platform.js +3 -0
- package/lib/platform-bootstrap.d.ts +1 -0
- package/lib/platform-bootstrap.js +85 -0
- package/package.json +1 -1
|
@@ -17,14 +17,311 @@ import { setPlatformChild, forwardFromPlatform } from './ipc-bridge.js';
|
|
|
17
17
|
const initRequire = () => { };
|
|
18
18
|
initRequire.resolve = () => '';
|
|
19
19
|
const require$1 = module$1?.createRequire?.(import.meta.url) ?? initRequire;
|
|
20
|
-
|
|
20
|
+
const createInitialState = () => ({
|
|
21
|
+
phase: 'idle',
|
|
22
|
+
protocolVersion: 'legacy',
|
|
23
|
+
transportMode: 'unknown',
|
|
24
|
+
restartCount: 0,
|
|
25
|
+
consecutiveFailures: 0,
|
|
26
|
+
legacyReadyMode: false,
|
|
27
|
+
bootTimings: {},
|
|
28
|
+
lastError: null
|
|
29
|
+
});
|
|
30
|
+
let platformManager = null;
|
|
31
|
+
let platformState = createInitialState();
|
|
32
|
+
let platformProcessConfig = null;
|
|
33
|
+
let platformBootstrapPath = '';
|
|
34
|
+
let platformEntryPath = '';
|
|
35
|
+
const normalizeErrorMessage = (error) => {
|
|
36
|
+
if (error instanceof Error) {
|
|
37
|
+
return error.message;
|
|
38
|
+
}
|
|
39
|
+
return typeof error === 'string' ? error : 'Unknown process adapter error';
|
|
40
|
+
};
|
|
41
|
+
const isDebugEnabled = () => process.env.NODE_ENV === 'development';
|
|
42
|
+
const debugLog = (message, data = {}) => {
|
|
43
|
+
if (!isDebugEnabled()) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
logger.debug?.({
|
|
47
|
+
message,
|
|
48
|
+
data
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
const clearTimer = (timer) => {
|
|
52
|
+
if (timer) {
|
|
53
|
+
clearTimeout(timer);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const clearManagerTimers = (manager) => {
|
|
57
|
+
clearTimer(manager?.controlTimer);
|
|
58
|
+
clearTimer(manager?.transportTimer);
|
|
59
|
+
clearTimer(manager?.appTimer);
|
|
60
|
+
clearTimer(manager?.legacyTransportTimer);
|
|
61
|
+
if (manager) {
|
|
62
|
+
manager.controlTimer = undefined;
|
|
63
|
+
manager.transportTimer = undefined;
|
|
64
|
+
manager.appTimer = undefined;
|
|
65
|
+
manager.legacyTransportTimer = undefined;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const buildConfig = () => {
|
|
21
69
|
const values = getConfigValue();
|
|
22
70
|
const pro = values?.process ?? {};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
71
|
+
return {
|
|
72
|
+
restartDelay: Number(pro?.restart_delay ?? 3000),
|
|
73
|
+
controlReadyTimeout: Number(pro?.control_ready_timeout ?? 10000),
|
|
74
|
+
transportReadyTimeout: Number(pro?.transport_ready_timeout ?? 15000),
|
|
75
|
+
appReadyTimeout: Number(pro?.app_ready_timeout ?? 30000),
|
|
76
|
+
maxRestartDelay: Number(pro?.max_restart_delay ?? 30000),
|
|
77
|
+
legacyTransportGraceMs: Number(pro?.legacy_transport_grace_ms ?? 50)
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
const resetBootState = () => {
|
|
81
|
+
platformState = {
|
|
82
|
+
...platformState,
|
|
83
|
+
phase: 'booting',
|
|
84
|
+
protocolVersion: 'legacy',
|
|
85
|
+
transportMode: 'unknown',
|
|
86
|
+
legacyReadyMode: false,
|
|
87
|
+
startedAt: Date.now(),
|
|
88
|
+
lastReadyAt: undefined,
|
|
89
|
+
lastTransportReadyAt: undefined,
|
|
90
|
+
lastAppReadyAt: undefined,
|
|
91
|
+
bootTimings: {},
|
|
92
|
+
lastError: null
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
const updateTransportBinding = (transportMode) => {
|
|
96
|
+
if (transportMode === 'ipc' && platformManager?.child) {
|
|
97
|
+
setPlatformChild(platformManager.child);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
setPlatformChild(null);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const markFailure = (error) => {
|
|
104
|
+
platformState = {
|
|
105
|
+
...platformState,
|
|
106
|
+
phase: 'failed',
|
|
107
|
+
lastError: error ? normalizeErrorMessage(error) : platformState.lastError,
|
|
108
|
+
consecutiveFailures: platformState.consecutiveFailures + 1
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
const markTransportReady = (transport, legacyReadyMode = false) => {
|
|
112
|
+
const now = Date.now();
|
|
113
|
+
if (!platformManager) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
platformManager.transportReady = true;
|
|
117
|
+
clearTimer(platformManager.transportTimer);
|
|
118
|
+
clearTimer(platformManager.legacyTransportTimer);
|
|
119
|
+
platformManager.transportTimer = undefined;
|
|
120
|
+
platformManager.legacyTransportTimer = undefined;
|
|
121
|
+
platformState = {
|
|
122
|
+
...platformState,
|
|
123
|
+
phase: platformState.lastAppReadyAt ? 'app_ready' : 'transport_ready',
|
|
124
|
+
transportMode: transport,
|
|
125
|
+
lastTransportReadyAt: now,
|
|
126
|
+
legacyReadyMode,
|
|
127
|
+
consecutiveFailures: 0,
|
|
128
|
+
bootTimings: {
|
|
129
|
+
...platformState.bootTimings,
|
|
130
|
+
readyToTransportReadyMs: platformState.lastReadyAt ? now - platformState.lastReadyAt : undefined,
|
|
131
|
+
transportReadyToAppReadyMs: platformState.lastAppReadyAt ? platformState.lastAppReadyAt - now : platformState.bootTimings.transportReadyToAppReadyMs
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
updateTransportBinding(transport);
|
|
135
|
+
if (legacyReadyMode) {
|
|
136
|
+
debugLog('platform adapter fallback to legacy transport ready');
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
const scheduleRestart = (reason) => {
|
|
140
|
+
if (!platformProcessConfig || !platformBootstrapPath || !platformEntryPath) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const baseDelay = platformProcessConfig.restartDelay;
|
|
144
|
+
const delay = Math.min(baseDelay * 2 ** Math.max(platformState.consecutiveFailures - 1, 0), platformProcessConfig.maxRestartDelay);
|
|
145
|
+
platformState = {
|
|
146
|
+
...platformState,
|
|
147
|
+
restartCount: platformState.restartCount + 1
|
|
27
148
|
};
|
|
149
|
+
debugLog('schedule platform adapter restart', { reason, delay });
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
void startPlatformAdapterWithFallback();
|
|
152
|
+
}, delay);
|
|
153
|
+
};
|
|
154
|
+
const cleanupManager = (manager) => {
|
|
155
|
+
clearManagerTimers(manager);
|
|
156
|
+
if (manager?.child) {
|
|
157
|
+
manager.child.removeAllListeners();
|
|
158
|
+
}
|
|
159
|
+
setPlatformChild(null);
|
|
160
|
+
if (platformManager === manager) {
|
|
161
|
+
platformManager = null;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
const startByImport = async () => {
|
|
165
|
+
try {
|
|
166
|
+
const importPath = platformEntryPath.startsWith('file://') ? platformEntryPath : `file://${platformEntryPath}`;
|
|
167
|
+
const mod = await import(importPath);
|
|
168
|
+
const run = typeof mod.default === 'function' ? mod.default : typeof mod.main === 'function' ? mod.main : null;
|
|
169
|
+
if (typeof run !== 'function') {
|
|
170
|
+
throw new Error('Platform entry must export a callable default or main function');
|
|
171
|
+
}
|
|
172
|
+
await run();
|
|
173
|
+
platformState = {
|
|
174
|
+
...platformState,
|
|
175
|
+
phase: 'app_ready',
|
|
176
|
+
protocolVersion: 'legacy',
|
|
177
|
+
transportMode: 'import',
|
|
178
|
+
consecutiveFailures: 0,
|
|
179
|
+
lastTransportReadyAt: Date.now(),
|
|
180
|
+
lastAppReadyAt: Date.now()
|
|
181
|
+
};
|
|
182
|
+
debugLog('platform adapter started via import fallback');
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
logger?.error?.({
|
|
186
|
+
code: ResultCode.Fail,
|
|
187
|
+
message: 'import 启动平台连接失败',
|
|
188
|
+
data: error
|
|
189
|
+
});
|
|
190
|
+
markFailure(error);
|
|
191
|
+
scheduleRestart('import_fallback_failed');
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const handleControlReady = (manager, message) => {
|
|
195
|
+
const protocolVersion = message.protocolVersion === 'v2' ? 'v2' : 'legacy';
|
|
196
|
+
const now = Date.now();
|
|
197
|
+
manager.protocolVersion = protocolVersion;
|
|
198
|
+
clearTimer(manager.controlTimer);
|
|
199
|
+
manager.controlTimer = undefined;
|
|
200
|
+
platformState = {
|
|
201
|
+
...platformState,
|
|
202
|
+
phase: 'control_ready',
|
|
203
|
+
protocolVersion,
|
|
204
|
+
legacyReadyMode: protocolVersion === 'legacy',
|
|
205
|
+
lastReadyAt: now,
|
|
206
|
+
bootTimings: {
|
|
207
|
+
...platformState.bootTimings,
|
|
208
|
+
forkToReadyMs: platformState.startedAt ? now - platformState.startedAt : undefined
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
manager.child?.send?.({ type: 'start' });
|
|
212
|
+
if (protocolVersion === 'v2') {
|
|
213
|
+
manager.transportTimer = setTimeout(() => {
|
|
214
|
+
logger?.warn?.({
|
|
215
|
+
code: ResultCode.Fail,
|
|
216
|
+
message: '平台连接进程未在规定时间内建立通讯层,准备降级/重启',
|
|
217
|
+
data: null
|
|
218
|
+
});
|
|
219
|
+
manager.isKilling = true;
|
|
220
|
+
manager.fallbackToImportOnExit = Boolean(process.env.port);
|
|
221
|
+
markFailure('transport_ready_timeout');
|
|
222
|
+
try {
|
|
223
|
+
manager.child?.kill();
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
cleanupManager(manager);
|
|
227
|
+
if (manager.fallbackToImportOnExit) {
|
|
228
|
+
void startByImport();
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
scheduleRestart('transport_ready_timeout');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}, platformProcessConfig?.transportReadyTimeout ?? 15000);
|
|
235
|
+
manager.appTimer = setTimeout(() => {
|
|
236
|
+
logger?.warn?.({
|
|
237
|
+
code: ResultCode.Warn,
|
|
238
|
+
message: '平台连接进程业务初始化较慢,尚未收到 app_ready',
|
|
239
|
+
data: null
|
|
240
|
+
});
|
|
241
|
+
}, platformProcessConfig?.appReadyTimeout ?? 30000);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
const legacyTransportMode = process.env.__ALEMON_DIRECT_SOCK ? 'direct' : 'ipc';
|
|
245
|
+
manager.legacyTransportTimer = setTimeout(() => {
|
|
246
|
+
if (!manager.transportReady) {
|
|
247
|
+
markTransportReady(legacyTransportMode, true);
|
|
248
|
+
}
|
|
249
|
+
}, platformProcessConfig?.legacyTransportGraceMs ?? 50);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
const handleMessage = (manager, message) => {
|
|
253
|
+
const data = typeof message === 'string' ? JSON.parse(message) : message;
|
|
254
|
+
if (data?.type === 'ready') {
|
|
255
|
+
handleControlReady(manager, data);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (data?.type === 'transport_ready') {
|
|
259
|
+
markTransportReady(data.transport ?? 'unknown');
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
if (data?.type === 'app_ready') {
|
|
263
|
+
const now = Date.now();
|
|
264
|
+
manager.appReady = true;
|
|
265
|
+
clearTimer(manager.appTimer);
|
|
266
|
+
manager.appTimer = undefined;
|
|
267
|
+
platformState = {
|
|
268
|
+
...platformState,
|
|
269
|
+
phase: 'app_ready',
|
|
270
|
+
lastAppReadyAt: now,
|
|
271
|
+
bootTimings: {
|
|
272
|
+
...platformState.bootTimings,
|
|
273
|
+
transportReadyToAppReadyMs: platformState.lastTransportReadyAt
|
|
274
|
+
? now - platformState.lastTransportReadyAt
|
|
275
|
+
: platformState.bootTimings.transportReadyToAppReadyMs
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (data?.type === 'boot_error') {
|
|
281
|
+
platformState = {
|
|
282
|
+
...platformState,
|
|
283
|
+
lastError: normalizeErrorMessage(data.error?.message ?? data.error)
|
|
284
|
+
};
|
|
285
|
+
logger?.warn?.({
|
|
286
|
+
code: ResultCode.Fail,
|
|
287
|
+
message: `平台连接进程启动阶段失败: ${String(data.stage ?? 'unknown')}`,
|
|
288
|
+
data: data.error ?? null
|
|
289
|
+
});
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
if (data?.type === 'ipc:data') {
|
|
293
|
+
forwardFromPlatform(data.data);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
const getPlatformAdapterState = () => ({
|
|
297
|
+
...platformState,
|
|
298
|
+
bootTimings: { ...platformState.bootTimings }
|
|
299
|
+
});
|
|
300
|
+
function restartPlatformAdapter() {
|
|
301
|
+
if (!platformManager?.child) {
|
|
302
|
+
void startPlatformAdapterWithFallback();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (platformManager.restartRequested) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
platformManager.restartRequested = true;
|
|
309
|
+
platformManager.isKilling = true;
|
|
310
|
+
platformState = {
|
|
311
|
+
...platformState,
|
|
312
|
+
phase: 'stopping'
|
|
313
|
+
};
|
|
314
|
+
clearManagerTimers(platformManager);
|
|
315
|
+
try {
|
|
316
|
+
platformManager.child.kill();
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
cleanupManager(platformManager);
|
|
320
|
+
scheduleRestart('manual_restart');
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function startPlatformAdapterWithFallback() {
|
|
324
|
+
platformProcessConfig = buildConfig();
|
|
28
325
|
const platformPath = process.env.platform;
|
|
29
326
|
if (!platformPath) {
|
|
30
327
|
logger?.error?.({
|
|
@@ -32,188 +329,119 @@ function startPlatformAdapterWithFallback() {
|
|
|
32
329
|
message: '未配置平台连接路径',
|
|
33
330
|
data: null
|
|
34
331
|
});
|
|
35
|
-
|
|
332
|
+
platformState = {
|
|
333
|
+
...platformState,
|
|
334
|
+
phase: 'failed',
|
|
335
|
+
lastError: 'missing platform path'
|
|
336
|
+
};
|
|
337
|
+
return Promise.resolve();
|
|
36
338
|
}
|
|
37
|
-
let modulePath = '';
|
|
38
|
-
let isForkFailed = false;
|
|
39
|
-
let imported = false;
|
|
40
339
|
try {
|
|
41
|
-
|
|
340
|
+
platformEntryPath = require$1.resolve(platformPath);
|
|
341
|
+
platformBootstrapPath = require$1.resolve('../../platform-bootstrap.js');
|
|
42
342
|
}
|
|
43
|
-
catch {
|
|
343
|
+
catch (error) {
|
|
44
344
|
logger?.warn?.({
|
|
45
345
|
code: ResultCode.Fail,
|
|
46
346
|
message: '平台连接包未支持 require',
|
|
47
|
-
data:
|
|
347
|
+
data: error
|
|
48
348
|
});
|
|
49
|
-
|
|
349
|
+
markFailure(error);
|
|
350
|
+
return Promise.resolve();
|
|
50
351
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
logger?.debug?.({
|
|
63
|
-
code: ResultCode.Ok,
|
|
64
|
-
message: '通过 import 启动平台连接完成',
|
|
65
|
-
data: null
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
logger?.warn?.({
|
|
70
|
-
code: ResultCode.Fail,
|
|
71
|
-
message: '通过 import 启动平台连接,但未找到默认导出函数',
|
|
72
|
-
data: null
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
logger?.error?.({
|
|
78
|
-
code: ResultCode.Fail,
|
|
79
|
-
message: 'import 启动平台连接失败',
|
|
80
|
-
data: error
|
|
81
|
-
});
|
|
82
|
-
}
|
|
352
|
+
if (platformManager?.child && platformManager.child.exitCode === null && !platformManager.child.killed) {
|
|
353
|
+
return Promise.resolve();
|
|
354
|
+
}
|
|
355
|
+
resetBootState();
|
|
356
|
+
const manager = {
|
|
357
|
+
isKilling: false,
|
|
358
|
+
restartRequested: false,
|
|
359
|
+
transportReady: false,
|
|
360
|
+
appReady: false,
|
|
361
|
+
protocolVersion: 'legacy',
|
|
362
|
+
fallbackToImportOnExit: false
|
|
83
363
|
};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
364
|
+
platformManager = manager;
|
|
365
|
+
manager.controlTimer = setTimeout(() => {
|
|
366
|
+
logger?.error?.({
|
|
367
|
+
code: ResultCode.Fail,
|
|
368
|
+
message: '平台连接进程未及时发送 ready,正在重启',
|
|
369
|
+
data: null
|
|
370
|
+
});
|
|
371
|
+
manager.isKilling = true;
|
|
372
|
+
markFailure('control_ready_timeout');
|
|
373
|
+
try {
|
|
374
|
+
manager.child?.kill();
|
|
87
375
|
}
|
|
88
|
-
|
|
89
|
-
|
|
376
|
+
catch {
|
|
377
|
+
cleanupManager(manager);
|
|
378
|
+
scheduleRestart('control_ready_timeout');
|
|
90
379
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (manager.restarted || imported) {
|
|
380
|
+
}, platformProcessConfig.controlReadyTimeout);
|
|
381
|
+
try {
|
|
382
|
+
manager.child = childProcess.fork(platformBootstrapPath, [], {
|
|
383
|
+
execArgv: process.execArgv,
|
|
384
|
+
env: {
|
|
385
|
+
...process.env,
|
|
386
|
+
__ALEMON_IPC: '1',
|
|
387
|
+
__ALEMON_PLATFORM_ENTRY: platformEntryPath
|
|
388
|
+
},
|
|
389
|
+
serialization: 'advanced'
|
|
390
|
+
});
|
|
391
|
+
manager.child.on('exit', (code, signal) => {
|
|
392
|
+
const fallbackToImportOnExit = manager.fallbackToImportOnExit;
|
|
393
|
+
cleanupManager(manager);
|
|
394
|
+
if (fallbackToImportOnExit) {
|
|
395
|
+
void startByImport();
|
|
108
396
|
return;
|
|
109
397
|
}
|
|
110
|
-
manager.
|
|
111
|
-
|
|
112
|
-
setTimeout(() => {
|
|
113
|
-
if (!imported && !isForkFailed) {
|
|
114
|
-
startByFork();
|
|
115
|
-
}
|
|
116
|
-
}, CONFIG.RESTART_DELAY);
|
|
117
|
-
};
|
|
118
|
-
const handleForkFailure = (error) => {
|
|
119
|
-
if (imported) {
|
|
398
|
+
if (manager.isKilling || manager.restartRequested) {
|
|
399
|
+
scheduleRestart(manager.restartRequested ? 'manual_restart' : 'timeout_or_kill');
|
|
120
400
|
return;
|
|
121
401
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
402
|
+
logger?.warn?.({
|
|
403
|
+
code: ResultCode.Fail,
|
|
404
|
+
message: `平台连接子进程已退出,code=${code}, signal=${signal},稍后自动重启`,
|
|
405
|
+
data: null
|
|
406
|
+
});
|
|
407
|
+
markFailure(`exit:${code ?? 'null'}:${signal ?? 'null'}`);
|
|
408
|
+
scheduleRestart('unexpected_exit');
|
|
409
|
+
});
|
|
410
|
+
manager.child.on('message', message => {
|
|
411
|
+
try {
|
|
412
|
+
handleMessage(manager, message);
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
125
415
|
logger?.error?.({
|
|
126
416
|
code: ResultCode.Fail,
|
|
127
|
-
message: '
|
|
417
|
+
message: '平台连接进程通信数据格式错误',
|
|
128
418
|
data: error
|
|
129
419
|
});
|
|
130
|
-
return;
|
|
131
420
|
}
|
|
132
|
-
|
|
421
|
+
});
|
|
422
|
+
manager.child.on('error', error => {
|
|
423
|
+
logger?.error?.({
|
|
133
424
|
code: ResultCode.Fail,
|
|
134
|
-
message: '
|
|
425
|
+
message: '平台连接子进程发生错误',
|
|
135
426
|
data: error
|
|
136
427
|
});
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
};
|
|
155
|
-
try {
|
|
156
|
-
manager.child = childProcess.fork(modulePath, [], {
|
|
157
|
-
execArgv: process.execArgv,
|
|
158
|
-
env: { ...process.env, __ALEMON_IPC: '1' },
|
|
159
|
-
serialization: 'advanced'
|
|
160
|
-
});
|
|
161
|
-
manager.timer = setTimeout(checkTimeout, CONFIG.FORK_TIMEOUT);
|
|
162
|
-
manager.child.on('exit', (code, signal) => {
|
|
163
|
-
cleanup();
|
|
164
|
-
if (manager.isKilling) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
if (!imported) {
|
|
168
|
-
logger?.warn?.({
|
|
169
|
-
code: ResultCode.Fail,
|
|
170
|
-
message: `平台连接子进程已退出,code=${code}, signal=${signal},${CONFIG.FORK_RESTART_DELAY / 1000}秒后自动重启`,
|
|
171
|
-
data: null
|
|
172
|
-
});
|
|
173
|
-
restart();
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
manager.child.on('message', (message) => {
|
|
177
|
-
try {
|
|
178
|
-
const data = typeof message === 'string' ? JSON.parse(message) : message;
|
|
179
|
-
if (data?.type === 'ready') {
|
|
180
|
-
if (manager.ready) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
manager.ready = true;
|
|
184
|
-
if (manager.timer) {
|
|
185
|
-
clearTimeout(manager.timer);
|
|
186
|
-
manager.timer = undefined;
|
|
187
|
-
}
|
|
188
|
-
setPlatformChild(manager.child);
|
|
189
|
-
logger?.debug?.({
|
|
190
|
-
code: ResultCode.Ok,
|
|
191
|
-
message: '平台连接已就绪(IPC)',
|
|
192
|
-
data: null
|
|
193
|
-
});
|
|
194
|
-
manager.child?.send?.({ type: 'start' });
|
|
195
|
-
}
|
|
196
|
-
else if (data?.type === 'ipc:data') {
|
|
197
|
-
forwardFromPlatform(data.data);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
logger?.error?.({
|
|
202
|
-
code: ResultCode.Fail,
|
|
203
|
-
message: '平台连接进程通信数据格式错误',
|
|
204
|
-
data: error
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
manager.child.on('error', error => {
|
|
209
|
-
handleForkFailure(error);
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
catch (error) {
|
|
213
|
-
handleForkFailure(error);
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
startByFork();
|
|
428
|
+
platformState = {
|
|
429
|
+
...platformState,
|
|
430
|
+
lastError: normalizeErrorMessage(error)
|
|
431
|
+
};
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
cleanupManager(manager);
|
|
436
|
+
logger?.warn?.({
|
|
437
|
+
code: ResultCode.Fail,
|
|
438
|
+
message: 'fork 启动平台连接失败',
|
|
439
|
+
data: error
|
|
440
|
+
});
|
|
441
|
+
markFailure(error);
|
|
442
|
+
scheduleRestart('fork_error');
|
|
443
|
+
}
|
|
444
|
+
return Promise.resolve();
|
|
217
445
|
}
|
|
218
446
|
|
|
219
|
-
export { startPlatformAdapterWithFallback };
|
|
447
|
+
export { getPlatformAdapterState, restartPlatformAdapter, startPlatformAdapterWithFallback };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type AdapterPhase = 'idle' | 'booting' | 'control_ready' | 'transport_ready' | 'app_ready' | 'stopping' | 'failed';
|
|
2
|
+
export type AdapterProtocolVersion = 'legacy' | 'v2';
|
|
3
|
+
export type AdapterTransportMode = 'unknown' | 'ipc' | 'direct' | 'ws' | 'import';
|
|
4
|
+
export type AdapterBootTimings = {
|
|
5
|
+
forkToReadyMs?: number;
|
|
6
|
+
readyToTransportReadyMs?: number;
|
|
7
|
+
transportReadyToAppReadyMs?: number;
|
|
8
|
+
};
|
|
9
|
+
export type ProcessAdapterState = {
|
|
10
|
+
phase: AdapterPhase;
|
|
11
|
+
protocolVersion: AdapterProtocolVersion;
|
|
12
|
+
transportMode: AdapterTransportMode;
|
|
13
|
+
restartCount: number;
|
|
14
|
+
consecutiveFailures: number;
|
|
15
|
+
legacyReadyMode: boolean;
|
|
16
|
+
startedAt?: number;
|
|
17
|
+
lastReadyAt?: number;
|
|
18
|
+
lastTransportReadyAt?: number;
|
|
19
|
+
lastAppReadyAt?: number;
|
|
20
|
+
bootTimings: AdapterBootTimings;
|
|
21
|
+
lastError?: string | null;
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/lib/global.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ declare global {
|
|
|
9
9
|
var __options: StartOptions;
|
|
10
10
|
var __sandbox: boolean | undefined;
|
|
11
11
|
var __client_loaded: boolean | undefined;
|
|
12
|
+
var __platform_bootstrap_loaded: boolean | undefined;
|
|
12
13
|
var __publicIp: string | undefined;
|
|
13
14
|
var logger: LoggerUtils;
|
|
14
15
|
var alemonjsCore: {
|
|
@@ -46,6 +47,8 @@ declare global {
|
|
|
46
47
|
platform?: string;
|
|
47
48
|
port?: string;
|
|
48
49
|
input?: string;
|
|
50
|
+
__ALEMON_PLATFORM_ENTRY?: string;
|
|
51
|
+
__ALEMON_DIRECT_SOCK?: string;
|
|
49
52
|
NODE_ENV?: 'development' | 'production';
|
|
50
53
|
}
|
|
51
54
|
}
|
package/lib/index.js
CHANGED
|
@@ -49,6 +49,8 @@ export { expendMiddleware } from './application/runtime/event-processor-middlewa
|
|
|
49
49
|
export { expendSubscribe, expendSubscribeCreate, expendSubscribeMount, expendSubscribeUnmount } from './application/runtime/event-processor-subscribe.js';
|
|
50
50
|
export { finishCurrentTrace, getCurrentAppName, getCurrentEvent, getCurrentNext, getCurrentPhase, markEventSendAttempt, markEventSendFailure, markEventSendSuccess, recordEventSendResults, withEventContext, withProcessorTrace } from './application/runtime/hook-event-context.js';
|
|
51
51
|
export { getConfig, getConfigValue, onWatchConfigValue } from './common/config.js';
|
|
52
|
+
export { getModuleAdapterState, restartModuleAdapter, startModuleAdapter } from './core/process/module.js';
|
|
53
|
+
export { getPlatformAdapterState, restartPlatformAdapter, startPlatformAdapterWithFallback } from './core/process/platform.js';
|
|
52
54
|
export { loadChildren, loadChildrenFile } from './application/runtime/load-modules/loadChild.js';
|
|
53
55
|
export { loadModels, run } from './application/runtime/load-modules/load.js';
|
|
54
56
|
export { normalizeRoutePath, parseMessageText } from './application/router/parser.js';
|
package/lib/main.d.ts
CHANGED
package/lib/main.js
CHANGED