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 CHANGED
@@ -243,4 +243,4 @@ cbp:
243
243
  user-agent: 'platform' # 平台标识
244
244
  x-device-id: 'auto-generated' # 设备ID(自动生成)
245
245
  x-full-receive: '0' # 是否全量接收:'1' 开启,'0' 关闭
246
- ```
246
+ ```
@@ -1,8 +1,6 @@
1
1
  import childProcess from 'child_process';
2
2
  import { ResultCode } from '../core/variable.js';
3
- import 'fs';
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 (e) {
21
+ catch (error) {
18
22
  logger?.warn?.({
19
23
  code: ResultCode.Fail,
20
- message: '模块加载进程启动失败,尝试使用 fork 模式启动',
21
- data: e
24
+ message: '模块加载进程启动失败',
25
+ data: error
22
26
  });
23
27
  return;
24
28
  }
25
29
  const startByFork = () => {
26
- let restarted = false;
27
- let ready = false;
28
- let child;
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
- if (child) {
35
- child.removeAllListeners();
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.kill();
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
- const checkTimeout = () => {
50
- if (!ready) {
51
- logger?.error?.({
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},3秒后自动重启`,
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', msg => {
81
+ manager.child.on('message', (message) => {
74
82
  try {
75
- const data = typeof msg === 'string' ? JSON.parse(msg) : msg;
83
+ const data = typeof message === 'string' ? JSON.parse(message) : message;
76
84
  if (data?.type === 'ready') {
77
- ready = true;
78
- clearTimeout(timer);
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 (err) {
95
+ catch (error) {
88
96
  logger?.error?.({
89
97
  code: ResultCode.Fail,
90
98
  message: '模块加载进程通信数据格式错误',
91
- data: err
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 (err) {
111
+ catch (error) {
97
112
  logger?.warn?.({
98
113
  code: ResultCode.Fail,
99
114
  message: 'fork 启动模块加载失败',
100
- data: err
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>;
@@ -1,8 +1,6 @@
1
1
  import childProcess from 'child_process';
2
2
  import { ResultCode } from '../core/variable.js';
3
- import 'fs';
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(process.env.platform);
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,降级为 import 加载, 请升级对应的平台连接包以提高进程稳定性',
36
+ message: '平台连接包未支持 require',
22
37
  data: null
23
38
  });
24
39
  return;
25
40
  }
26
- let imported = false;
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
- let restarted = false;
32
- let ready = false;
33
- let child;
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
- restarted = true;
39
- if (child) {
40
- child.removeAllListeners();
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.kill();
129
+ manager.child?.kill();
130
+ }
131
+ catch {
43
132
  }
44
- catch { }
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
- const checkTimeout = async () => {
55
- if (!ready && !imported) {
56
- logger?.warn?.({
57
- code: ResultCode.Fail,
58
- message: '平台连接未及时响应(未发送 ready 消息),降级为 import 加载, 请升级对应的平台连接包以提高进程稳定性',
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},3秒后自动重启`,
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', msg => {
155
+ manager.child.on('message', (message) => {
81
156
  try {
82
- const data = typeof msg === 'string' ? JSON.parse(msg) : msg;
157
+ const data = typeof message === 'string' ? JSON.parse(message) : message;
83
158
  if (data?.type === 'ready') {
84
- ready = true;
85
- clearTimeout(timer);
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 (err) {
172
+ catch (error) {
95
173
  logger?.error?.({
96
174
  code: ResultCode.Fail,
97
175
  message: '平台连接进程通信数据格式错误',
98
- data: err
176
+ data: error
99
177
  });
100
178
  }
101
179
  });
102
- }
103
- catch (err) {
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
- imported = true;
117
- try {
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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alemonjs",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "bot script",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",