@abtnode/core 1.16.47-beta-20250807-110715-19ad6b43 → 1.16.47
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/lib/blocklet/manager/disk.js +25 -28
- package/lib/blocklet/manager/ensure-blocklet-running.js +88 -95
- package/lib/blocklet/migration-dist/migration.cjs +1 -1
- package/lib/monitor/node-runtime-monitor.js +2 -1
- package/lib/team/manager.js +2 -2
- package/lib/util/blocklet.js +8 -10
- package/lib/util/docker/docker-exec-chown.js +7 -3
- package/lib/util/docker/docker-exec.js +20 -7
- package/lib/util/docker/parse-docker-options-from-pm2.js +1 -7
- package/lib/util/ensure-bun.js +1 -1
- package/package.json +27 -27
|
@@ -435,33 +435,31 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
435
435
|
await this.ensureAutoBackupJobs();
|
|
436
436
|
await this.ensureAutoCheckUpdateJobs();
|
|
437
437
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
restart
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
stop
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
});
|
|
464
|
-
}
|
|
438
|
+
ensureBlockletRunning.initialize({
|
|
439
|
+
restart: async (params) => {
|
|
440
|
+
await this.restart(params);
|
|
441
|
+
},
|
|
442
|
+
stop: async (params) => {
|
|
443
|
+
await this.stop(params);
|
|
444
|
+
},
|
|
445
|
+
createAuditLog: (params) => this.createAuditLog(params),
|
|
446
|
+
notification: (did, title, description, severity) => {
|
|
447
|
+
try {
|
|
448
|
+
this._createNotification(did, {
|
|
449
|
+
title,
|
|
450
|
+
description,
|
|
451
|
+
action: `/blocklets/${did}/overview`,
|
|
452
|
+
blockletDashboardAction: `${WELLKNOWN_SERVICE_PATH_PREFIX}/admin/blocklets`,
|
|
453
|
+
entityType: 'blocklet',
|
|
454
|
+
entityId: did,
|
|
455
|
+
severity,
|
|
456
|
+
});
|
|
457
|
+
} catch (err) {
|
|
458
|
+
logger.error('create notification failed', { err });
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
checkSystemHighLoad: (...args) => this.nodeAPI.runtimeMonitor.checkSystemHighLoad(...args),
|
|
462
|
+
});
|
|
465
463
|
}
|
|
466
464
|
|
|
467
465
|
async ensureJobs({ queue, getJobId, find, entity, action, interval, restoreCancelled }) {
|
|
@@ -922,7 +920,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
922
920
|
nodeInfo,
|
|
923
921
|
env,
|
|
924
922
|
...hookArgs,
|
|
925
|
-
timeout: 20000,
|
|
926
923
|
});
|
|
927
924
|
}
|
|
928
925
|
return hooks[hookName](b, {
|
|
@@ -12,16 +12,10 @@ const inProgressStatuses = [BlockletStatus.stopping, BlockletStatus.restarting,
|
|
|
12
12
|
class EnsureBlockletRunning {
|
|
13
13
|
initialized = false;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
whenCycleCheck = false;
|
|
16
16
|
|
|
17
17
|
// 每次任务的最小间隔时间
|
|
18
|
-
checkInterval = +process.env.ABT_NODE_ENSURE_RUNNING_CHECK_INTERVAL ||
|
|
19
|
-
|
|
20
|
-
// 首次任务的延迟时间
|
|
21
|
-
deferredTime = +process.env.ABT_NODE_ENSURE_RUNNING_DEFERRED_TIME || 30 * 1000;
|
|
22
|
-
|
|
23
|
-
// 每个重启任务(did + componentDids)的重启间隔为 2 min,如果 2 min 内重启过,就不会再重启
|
|
24
|
-
restartInterval = 1000 * 60 * 2;
|
|
18
|
+
checkInterval = +process.env.ABT_NODE_ENSURE_RUNNING_CHECK_INTERVAL || 180 * 1000;
|
|
25
19
|
|
|
26
20
|
everyBlockletCheckInterval = 2000;
|
|
27
21
|
|
|
@@ -41,7 +35,7 @@ class EnsureBlockletRunning {
|
|
|
41
35
|
|
|
42
36
|
fakeRunningBlocklets = {};
|
|
43
37
|
|
|
44
|
-
|
|
38
|
+
needRestartBlocklets = {};
|
|
45
39
|
|
|
46
40
|
restartingBlocklets = {};
|
|
47
41
|
|
|
@@ -52,23 +46,36 @@ class EnsureBlockletRunning {
|
|
|
52
46
|
// Ease to mock
|
|
53
47
|
isBlockletPortHealthy = isBlockletPortHealthy;
|
|
54
48
|
|
|
55
|
-
isBlockletPortHealthyWithRetries = async (blocklet,
|
|
49
|
+
isBlockletPortHealthyWithRetries = async (blocklet, fastCheck = false) => {
|
|
56
50
|
let error;
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
if (!this.whenCycleCheck) {
|
|
52
|
+
try {
|
|
53
|
+
// eslint-disable-next-line no-await-in-loop
|
|
54
|
+
await this.isBlockletPortHealthy(blocklet, {
|
|
55
|
+
minConsecutiveTime: 200,
|
|
56
|
+
timeout: 1000,
|
|
57
|
+
});
|
|
58
|
+
return true;
|
|
59
|
+
} catch (e) {
|
|
60
|
+
logger.error('blocklet port is not healthy', e);
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
59
64
|
|
|
60
|
-
for (let attempt = 0; attempt <
|
|
65
|
+
for (let attempt = 0; attempt < 10; attempt++) {
|
|
61
66
|
try {
|
|
62
67
|
// eslint-disable-next-line no-await-in-loop
|
|
63
68
|
await this.isBlockletPortHealthy(blocklet, {
|
|
64
69
|
minConsecutiveTime: 3000,
|
|
65
|
-
timeout,
|
|
70
|
+
timeout: 6000,
|
|
66
71
|
});
|
|
67
72
|
return true;
|
|
68
73
|
} catch (e) {
|
|
69
74
|
error = e;
|
|
70
75
|
// eslint-disable-next-line no-await-in-loop
|
|
71
|
-
await sleep(
|
|
76
|
+
await sleep(
|
|
77
|
+
fastCheck && this.whenCycleCheck ? this.everyBlockletDoingInterval : this.everyBlockletCheckInterval
|
|
78
|
+
);
|
|
72
79
|
}
|
|
73
80
|
}
|
|
74
81
|
logger.error('blocklet port is not healthy', error);
|
|
@@ -91,7 +98,9 @@ class EnsureBlockletRunning {
|
|
|
91
98
|
this.checkSystemHighLoad = checkSystemHighLoad;
|
|
92
99
|
logger.info('check and fix blocklet status interval', this.checkInterval);
|
|
93
100
|
const task = async () => {
|
|
94
|
-
|
|
101
|
+
if (this.whenCycleCheck) {
|
|
102
|
+
await sleep(this.checkInterval);
|
|
103
|
+
}
|
|
95
104
|
try {
|
|
96
105
|
await this.checkAndFix();
|
|
97
106
|
} catch (e) {
|
|
@@ -116,91 +125,72 @@ class EnsureBlockletRunning {
|
|
|
116
125
|
|
|
117
126
|
checkAndFix = async () => {
|
|
118
127
|
logger.info('check and fix blocklet status');
|
|
119
|
-
if (process.env.ABT_NODE_RESTART_RUNNING_COMPONENT === '1') {
|
|
120
|
-
logger.info('skip check and fix blocklet status because ABT_NODE_RESTART_RUNNING_COMPONENT is 1');
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
128
|
const systemHighLoad = this.checkSystemHighLoad({
|
|
125
129
|
maxCpus: this.highLoadCpu,
|
|
126
130
|
maxMem: this.highLoadMemory,
|
|
127
131
|
maxDisk: this.highLoadDisk,
|
|
128
132
|
});
|
|
129
133
|
|
|
130
|
-
if (systemHighLoad.isHighLoad) {
|
|
134
|
+
if (this.whenCycleCheck && systemHighLoad.isHighLoad) {
|
|
131
135
|
logger.warn('Skip once ensure blocklet running because system high load', systemHighLoad);
|
|
132
136
|
return;
|
|
133
137
|
}
|
|
138
|
+
|
|
134
139
|
this.runningBlocklets = {};
|
|
135
140
|
this.fakeRunningBlocklets = {};
|
|
136
|
-
this.
|
|
141
|
+
this.needRestartBlocklets = {};
|
|
137
142
|
|
|
143
|
+
const startTime = Date.now();
|
|
138
144
|
try {
|
|
139
145
|
await this.getRunningBlocklets();
|
|
140
146
|
await this.getFakeRunningBlocklets();
|
|
141
|
-
if (
|
|
147
|
+
if (!this.whenCycleCheck) {
|
|
142
148
|
await this.setFakeRunningToWaiting();
|
|
143
149
|
}
|
|
144
150
|
await this.restartFakeRunningBlocklets();
|
|
145
151
|
} catch (e) {
|
|
146
152
|
logger.error('ensure blocklet status failed', e);
|
|
147
153
|
}
|
|
154
|
+
logger.info(
|
|
155
|
+
`ensure blocklet status finished in ${Date.now() - startTime}ms. It's server first start: ${!this.whenCycleCheck}`
|
|
156
|
+
);
|
|
148
157
|
this.runningRootBlocklets = {};
|
|
149
|
-
this.
|
|
158
|
+
this.whenCycleCheck = true;
|
|
150
159
|
};
|
|
151
160
|
|
|
152
161
|
getRunningBlocklets = async () => {
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
for (const realBlocklet of blocklets) {
|
|
157
|
-
const { did } = realBlocklet.meta;
|
|
158
|
-
if (realBlocklet.children) {
|
|
159
|
-
for (const childBlocklet of realBlocklet.children) {
|
|
160
|
-
if (childBlocklet.status === BlockletStatus.running || childBlocklet.status === BlockletStatus.waiting) {
|
|
161
|
-
if (!this.runningBlocklets[did]) {
|
|
162
|
-
this.runningBlocklets[did] = [];
|
|
163
|
-
}
|
|
164
|
-
if (this.runningBlocklets[did].find((b) => b.meta.did === childBlocklet.meta.did)) {
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
this.runningBlocklets[did].push(childBlocklet);
|
|
168
|
-
this.runningRootBlocklets[did] = realBlocklet;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const blockletDoings = await this.states.blocklet.getBlocklets({
|
|
175
|
-
status: {
|
|
176
|
-
$in: inProgressStatuses,
|
|
177
|
-
},
|
|
178
|
-
});
|
|
162
|
+
const runningStatuses = this.whenCycleCheck
|
|
163
|
+
? [BlockletStatus.running, BlockletStatus.waiting, BlockletStatus.starting]
|
|
164
|
+
: [BlockletStatus.running, BlockletStatus.waiting, BlockletStatus.starting, BlockletStatus.error];
|
|
179
165
|
|
|
180
|
-
|
|
166
|
+
const blocklets = await this.states.blocklet.getBlocklets();
|
|
167
|
+
for (const rootBlocklet of blocklets) {
|
|
181
168
|
const { did } = rootBlocklet.meta;
|
|
182
169
|
if (rootBlocklet.children) {
|
|
183
170
|
for (const childBlocklet of rootBlocklet.children) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
171
|
+
const isRunning = runningStatuses.includes(childBlocklet.status);
|
|
172
|
+
const isInProgress = inProgressStatuses.includes(childBlocklet.status);
|
|
173
|
+
if (isRunning || isInProgress) {
|
|
188
174
|
if (!this.runningBlocklets[did]) {
|
|
189
175
|
this.runningBlocklets[did] = [];
|
|
190
176
|
}
|
|
177
|
+
if (this.runningBlocklets[did].find((b) => b.meta.did === childBlocklet.meta.did)) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
191
180
|
this.runningBlocklets[did].push(childBlocklet);
|
|
181
|
+
this.runningRootBlocklets[did] = rootBlocklet;
|
|
192
182
|
}
|
|
193
183
|
}
|
|
194
184
|
}
|
|
195
185
|
}
|
|
186
|
+
|
|
196
187
|
logger.info('get running blocklets', Object.keys(this.runningBlocklets).length);
|
|
197
188
|
};
|
|
198
189
|
|
|
199
190
|
getFakeRunningBlocklets = async () => {
|
|
200
|
-
|
|
201
|
-
const blockletDids = Object.keys(this.runningBlocklets);
|
|
191
|
+
const rootDids = Object.keys(this.runningBlocklets);
|
|
202
192
|
await pAll(
|
|
203
|
-
|
|
193
|
+
rootDids.map((did) => {
|
|
204
194
|
return async () => {
|
|
205
195
|
const blocklets = this.runningBlocklets[did];
|
|
206
196
|
// eslint-disable-next-line
|
|
@@ -241,7 +231,7 @@ class EnsureBlockletRunning {
|
|
|
241
231
|
);
|
|
242
232
|
};
|
|
243
233
|
}),
|
|
244
|
-
{ concurrency:
|
|
234
|
+
{ concurrency: 8 }
|
|
245
235
|
);
|
|
246
236
|
|
|
247
237
|
logger.info('get fake running blocklets', Object.keys(this.fakeRunningBlocklets).length);
|
|
@@ -257,7 +247,9 @@ class EnsureBlockletRunning {
|
|
|
257
247
|
blockletDids.map((did) => {
|
|
258
248
|
return async () => {
|
|
259
249
|
const blocklets = this.fakeRunningBlocklets[did];
|
|
260
|
-
const componentDids = blocklets
|
|
250
|
+
const componentDids = blocklets
|
|
251
|
+
.filter((b) => b.status === BlockletStatus.running || b.status === BlockletStatus.waiting)
|
|
252
|
+
.map((b) => b.meta.did);
|
|
261
253
|
try {
|
|
262
254
|
// eslint-disable-next-line
|
|
263
255
|
await this.states.blocklet.setBlockletStatus(did, BlockletStatus.waiting, { componentDids });
|
|
@@ -266,17 +258,11 @@ class EnsureBlockletRunning {
|
|
|
266
258
|
}
|
|
267
259
|
};
|
|
268
260
|
}),
|
|
269
|
-
{ concurrency:
|
|
261
|
+
{ concurrency: 8 }
|
|
270
262
|
);
|
|
271
263
|
};
|
|
272
264
|
|
|
273
265
|
restartFakeRunningBlocklets = async () => {
|
|
274
|
-
for (const key of Object.keys(this.restartingBlocklets)) {
|
|
275
|
-
if (Date.now() - this.restartingBlocklets[key] > this.restartInterval) {
|
|
276
|
-
delete this.restartingBlocklets[key];
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
266
|
// blocklet 一组组重启
|
|
281
267
|
const blockletDids = Object.keys(this.fakeRunningBlocklets);
|
|
282
268
|
await pAll(
|
|
@@ -286,7 +272,8 @@ class EnsureBlockletRunning {
|
|
|
286
272
|
const componentDids = blocklets.map((b) => b.meta.did);
|
|
287
273
|
if (componentDids.length > 0) {
|
|
288
274
|
const key = `${did}-${componentDids.join('-')}`;
|
|
289
|
-
|
|
275
|
+
this.needRestartBlocklets[key] = true;
|
|
276
|
+
if (this.restartingBlocklets[key] && this.restartingBlocklets[key] + this.checkInterval < Date.now()) {
|
|
290
277
|
return;
|
|
291
278
|
}
|
|
292
279
|
this.restartingBlocklets[key] = Date.now();
|
|
@@ -294,31 +281,36 @@ class EnsureBlockletRunning {
|
|
|
294
281
|
const blockletDisplayName = this.getDisplayNameByRootDid(did);
|
|
295
282
|
const restartTitle = 'Blocklet health check failed';
|
|
296
283
|
const restartDescription = `Blocklet ${blockletDisplayName} with components ${componentDids.map((v) => this.getDisplayName(blocklets.find((b) => b.meta.did === v))).join(', ')} health check failed, restarting...`;
|
|
297
|
-
this.
|
|
284
|
+
if (this.whenCycleCheck) {
|
|
285
|
+
this.notification(did, restartTitle, restartDescription, 'warning');
|
|
286
|
+
}
|
|
298
287
|
|
|
299
288
|
try {
|
|
300
289
|
logger.info('restart blocklet:', did, componentDids);
|
|
301
290
|
await this.restart({ did, componentDids, checkHealthImmediately: true });
|
|
302
|
-
this.
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
context: {
|
|
309
|
-
user: {
|
|
310
|
-
did,
|
|
311
|
-
role: 'daemon',
|
|
312
|
-
blockletDid: did,
|
|
313
|
-
fullName: blockletDisplayName,
|
|
314
|
-
elevated: false,
|
|
291
|
+
if (this.whenCycleCheck) {
|
|
292
|
+
this.createAuditLog({
|
|
293
|
+
action: 'ensureBlockletRunning',
|
|
294
|
+
args: {
|
|
295
|
+
teamDid: did,
|
|
296
|
+
componentDids,
|
|
315
297
|
},
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
298
|
+
context: {
|
|
299
|
+
user: {
|
|
300
|
+
did,
|
|
301
|
+
role: 'daemon',
|
|
302
|
+
blockletDid: did,
|
|
303
|
+
fullName: blockletDisplayName,
|
|
304
|
+
elevated: false,
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
result: {
|
|
308
|
+
title: restartTitle,
|
|
309
|
+
description: restartDescription,
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
322
314
|
delete this.restartingBlocklets[key];
|
|
323
315
|
} catch (e) {
|
|
324
316
|
logger.error('restart blocklet failed', did, componentDids, e);
|
|
@@ -327,15 +319,16 @@ class EnsureBlockletRunning {
|
|
|
327
319
|
}
|
|
328
320
|
this.errorStartBlocklets[key] += 1;
|
|
329
321
|
|
|
330
|
-
// 如果重启失败次数超过 3
|
|
331
|
-
if (this.errorStartBlocklets[key] >= 3) {
|
|
322
|
+
// 如果重启失败次数超过 3 次,则发送通知, 如果 server 是第一次启动遇到失败,则立刻发送通知
|
|
323
|
+
if (this.errorStartBlocklets[key] >= 3 || !this.whenCycleCheck) {
|
|
332
324
|
const title = 'Restart blocklet failed when health check failed';
|
|
333
325
|
const description = `Restart blocklet ${blockletDisplayName} with components ${componentDids.map((v) => this.getDisplayName(blocklets.find((b) => b.meta.did === v))).join(', ')} failed`;
|
|
334
326
|
this.notification(did, title, description, 'error');
|
|
335
327
|
delete this.errorStartBlocklets[key];
|
|
336
|
-
logger.error('restart many times blocklet failed
|
|
328
|
+
logger.error('restart many times blocklet failed', did, componentDids, e);
|
|
337
329
|
try {
|
|
338
|
-
|
|
330
|
+
// 失败了应该保持 error 状态
|
|
331
|
+
await this.states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
339
332
|
this.createAuditLog({
|
|
340
333
|
action: 'ensureBlockletRunning',
|
|
341
334
|
args: {
|
|
@@ -358,14 +351,14 @@ class EnsureBlockletRunning {
|
|
|
358
351
|
},
|
|
359
352
|
});
|
|
360
353
|
} catch (err) {
|
|
361
|
-
logger.error('
|
|
354
|
+
logger.error('ensure blocklet running, create audit log failed', did, componentDids, err);
|
|
362
355
|
}
|
|
363
356
|
}
|
|
364
357
|
}
|
|
365
358
|
}
|
|
366
359
|
};
|
|
367
360
|
}),
|
|
368
|
-
{ concurrency:
|
|
361
|
+
{ concurrency: 8 }
|
|
369
362
|
);
|
|
370
363
|
};
|
|
371
364
|
}
|
|
@@ -38918,7 +38918,7 @@ module.exports = require("zlib");
|
|
|
38918
38918
|
/***/ ((module) => {
|
|
38919
38919
|
|
|
38920
38920
|
"use strict";
|
|
38921
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.46","description":"","main":"lib/index.js","files":["lib"],"scripts":{"lint":"eslint tests lib --ignore-pattern \'tests/assets/*\'","lint:fix":"eslint --fix tests lib","test":"node tools/jest.js","coverage":"npm run test -- --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.46","@abtnode/auth":"1.16.46","@abtnode/certificate-manager":"1.16.46","@abtnode/client":"1.16.46","@abtnode/constant":"1.16.46","@abtnode/cron":"1.16.46","@abtnode/db-cache":"1.16.46","@abtnode/docker-utils":"1.16.46","@abtnode/logger":"1.16.46","@abtnode/models":"1.16.46","@abtnode/queue":"1.16.46","@abtnode/rbac":"1.16.46","@abtnode/router-provider":"1.16.46","@abtnode/static-server":"1.16.46","@abtnode/timemachine":"1.16.46","@abtnode/util":"1.16.46","@aigne/aigne-hub":"^0.4.
|
|
38921
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@abtnode/core","publishConfig":{"access":"public"},"version":"1.16.46","description":"","main":"lib/index.js","files":["lib"],"scripts":{"lint":"eslint tests lib --ignore-pattern \'tests/assets/*\'","lint:fix":"eslint --fix tests lib","test":"node tools/jest.js","coverage":"npm run test -- --coverage"},"keywords":[],"author":"wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)","license":"Apache-2.0","dependencies":{"@abtnode/analytics":"1.16.46","@abtnode/auth":"1.16.46","@abtnode/certificate-manager":"1.16.46","@abtnode/client":"1.16.46","@abtnode/constant":"1.16.46","@abtnode/cron":"1.16.46","@abtnode/db-cache":"1.16.46","@abtnode/docker-utils":"1.16.46","@abtnode/logger":"1.16.46","@abtnode/models":"1.16.46","@abtnode/queue":"1.16.46","@abtnode/rbac":"1.16.46","@abtnode/router-provider":"1.16.46","@abtnode/static-server":"1.16.46","@abtnode/timemachine":"1.16.46","@abtnode/util":"1.16.46","@aigne/aigne-hub":"^0.4.6","@arcblock/did":"1.21.2","@arcblock/did-connect-js":"1.21.2","@arcblock/did-ext":"1.21.2","@arcblock/did-motif":"^1.1.14","@arcblock/did-util":"1.21.2","@arcblock/event-hub":"1.21.2","@arcblock/jwt":"1.21.2","@arcblock/pm2-events":"^0.0.5","@arcblock/validator":"1.21.2","@arcblock/vc":"1.21.2","@blocklet/constant":"1.16.46","@blocklet/did-space-js":"^1.1.14","@blocklet/env":"1.16.46","@blocklet/error":"^0.2.5","@blocklet/meta":"1.16.46","@blocklet/resolver":"1.16.46","@blocklet/sdk":"1.16.46","@blocklet/store":"1.16.46","@blocklet/theme":"^3.1.3","@fidm/x509":"^1.2.1","@ocap/mcrypto":"1.21.2","@ocap/util":"1.21.2","@ocap/wallet":"1.21.2","@slack/webhook":"^5.0.4","archiver":"^7.0.1","axios":"^1.7.9","axon":"^2.0.3","chalk":"^4.1.2","cross-spawn":"^7.0.3","dayjs":"^1.11.13","deep-diff":"^1.0.2","detect-port":"^1.5.1","envfile":"^7.1.0","escape-string-regexp":"^4.0.0","fast-glob":"^3.3.2","filesize":"^10.1.1","flat":"^5.0.2","fs-extra":"^11.2.0","get-port":"^5.1.1","hasha":"^5.2.2","is-base64":"^1.1.0","is-cidr":"4","is-ip":"3","is-url":"^1.2.4","joi":"17.12.2","joi-extension-semver":"^5.0.0","js-yaml":"^4.1.0","kill-port":"^2.0.1","lodash":"^4.17.21","node-stream-zip":"^1.15.0","p-all":"^3.0.0","p-limit":"^3.1.0","p-map":"^4.0.0","p-retry":"^4.6.2","p-wait-for":"^3.2.0","private-ip":"^2.3.4","rate-limiter-flexible":"^5.0.5","read-last-lines":"^1.8.0","semver":"^7.6.3","sequelize":"^6.35.0","shelljs":"^0.8.5","slugify":"^1.6.6","ssri":"^8.0.1","stream-throttle":"^0.1.3","stream-to-promise":"^3.0.0","systeminformation":"^5.23.3","tail":"^2.2.4","tar":"^6.1.11","transliteration":"^2.3.5","ua-parser-js":"^1.0.2","ufo":"^1.5.3","uuid":"^11.1.0","valid-url":"^1.0.9","which":"^2.0.2","xbytes":"^1.8.0"},"devDependencies":{"expand-tilde":"^2.0.2","express":"^4.18.2","jest":"^29.7.0","unzipper":"^0.10.11"},"gitHead":"e5764f753181ed6a7c615cd4fc6682aacf0cb7cd"}');
|
|
38922
38922
|
|
|
38923
38923
|
/***/ }),
|
|
38924
38924
|
|
|
@@ -234,7 +234,8 @@ class NodeRuntimeMonitor extends EventEmitter {
|
|
|
234
234
|
if (cpus.some((v) => v > maxCpus) && memory > maxMem) {
|
|
235
235
|
highType = 'cpu and memory';
|
|
236
236
|
}
|
|
237
|
-
|
|
237
|
+
// 1 表示虚拟盘,不参与计算
|
|
238
|
+
if (disks.some((v) => v !== 1 && v > maxDisk)) {
|
|
238
239
|
highType = 'disk';
|
|
239
240
|
}
|
|
240
241
|
if (highType) {
|
package/lib/team/manager.js
CHANGED
|
@@ -495,7 +495,7 @@ class TeamManager extends EventEmitter {
|
|
|
495
495
|
// 获取 notification state
|
|
496
496
|
const notificationState = await this.getNotificationState(teamDid);
|
|
497
497
|
if (!notificationState) {
|
|
498
|
-
|
|
498
|
+
return undefined;
|
|
499
499
|
}
|
|
500
500
|
|
|
501
501
|
// 检查通知是否已存在
|
|
@@ -505,7 +505,7 @@ class TeamManager extends EventEmitter {
|
|
|
505
505
|
|
|
506
506
|
if (!receivers?.length && process.env.NODE_ENV !== 'test') {
|
|
507
507
|
logger.warn('No valid receivers', { teamDid, receiver });
|
|
508
|
-
|
|
508
|
+
return undefined;
|
|
509
509
|
}
|
|
510
510
|
|
|
511
511
|
const notificationActor = notification?.activity?.actor || payload.activity?.actor;
|
package/lib/util/blocklet.js
CHANGED
|
@@ -145,7 +145,7 @@ const getBlockletEngineNameByPlatform = (meta) => getBlockletEngine(meta).interp
|
|
|
145
145
|
const startLock = new DBCache(() => ({
|
|
146
146
|
...getAbtNodeRedisAndSQLiteUrl(),
|
|
147
147
|
prefix: 'blocklet-start-locks2',
|
|
148
|
-
ttl: 1000 * 60 *
|
|
148
|
+
ttl: 1000 * 60 * 3,
|
|
149
149
|
}));
|
|
150
150
|
|
|
151
151
|
const blockletCache = new DBCache(() => ({
|
|
@@ -819,23 +819,21 @@ const startBlockletProcess = async (
|
|
|
819
819
|
* @returns
|
|
820
820
|
*/
|
|
821
821
|
async (b, { ancestors }) => {
|
|
822
|
-
const lockName =
|
|
823
|
-
blocklet.meta.did,
|
|
824
|
-
blocklet.meta.version,
|
|
825
|
-
blocklet.meta.group,
|
|
826
|
-
b.meta.did,
|
|
827
|
-
b.meta.version,
|
|
828
|
-
b.meta.group,
|
|
829
|
-
].join('__');
|
|
822
|
+
const lockName = `${blocklet.meta.did}-${b.meta.did}`;
|
|
830
823
|
|
|
824
|
+
// 如果锁存在,则跳过执行
|
|
825
|
+
if (!(await startLock.hasExpired(lockName))) {
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
831
828
|
await startLock.acquire(lockName);
|
|
829
|
+
|
|
832
830
|
try {
|
|
833
831
|
await startBlockletTask(b, { ancestors });
|
|
834
832
|
} finally {
|
|
835
833
|
startLock.releaseLock(lockName);
|
|
836
834
|
}
|
|
837
835
|
},
|
|
838
|
-
{ parallel: true, concurrencyLimit:
|
|
836
|
+
{ parallel: true, concurrencyLimit: 4 }
|
|
839
837
|
);
|
|
840
838
|
};
|
|
841
839
|
|
|
@@ -12,7 +12,7 @@ const { createDockerImage } = require('./create-docker-image');
|
|
|
12
12
|
|
|
13
13
|
const lockFile = new DBCache(() => ({
|
|
14
14
|
prefix: 'docker-exec-chown-locks',
|
|
15
|
-
ttl: 1000 * 60 *
|
|
15
|
+
ttl: 1000 * 60 * 3,
|
|
16
16
|
...getAbtNodeRedisAndSQLiteUrl(),
|
|
17
17
|
}));
|
|
18
18
|
|
|
@@ -53,10 +53,14 @@ async function dockerExecChown({ name, dirs, code = 777, force = false }) {
|
|
|
53
53
|
return `chmod ${code === 750 ? '' : '-R'} ${code} ${path.join(baseDir, dir.replace(process.env.ABT_NODE_DATA_DIR, ''))}`;
|
|
54
54
|
})
|
|
55
55
|
.join(' && ');
|
|
56
|
-
const realName = parseDockerName(name, 'docker-exec-chown');
|
|
57
|
-
const startTime = Date.now();
|
|
58
56
|
|
|
57
|
+
const startTime = Date.now();
|
|
58
|
+
const realName = parseDockerName(name, 'docker-exec-chown');
|
|
59
|
+
if (!(await lockFile.hasExpired(realName))) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
59
62
|
await lockFile.acquire(realName);
|
|
63
|
+
|
|
60
64
|
try {
|
|
61
65
|
await promiseSpawn(
|
|
62
66
|
`docker rm -fv ${realName} > /dev/null 2>&1 || true && docker run --rm --name ${realName} ${volumes} ${image} sh -c '${command}'`,
|
|
@@ -2,10 +2,20 @@ const fs = require('fs').promises;
|
|
|
2
2
|
const fse = require('fs-extra');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const promiseSpawn = require('@abtnode/util/lib/promise-spawn');
|
|
5
|
+
const { DBCache, getAbtNodeRedisAndSQLiteUrl } = require('@abtnode/db-cache');
|
|
5
6
|
const logger = require('@abtnode/logger')('@abtnode/docker-exec');
|
|
7
|
+
|
|
6
8
|
const parseDockerOptionsFromPm2 = require('./parse-docker-options-from-pm2');
|
|
7
9
|
const { checkDockerInstalled } = require('./check-docker-installed');
|
|
8
10
|
|
|
11
|
+
const lock = new DBCache(() => {
|
|
12
|
+
return {
|
|
13
|
+
...getAbtNodeRedisAndSQLiteUrl(),
|
|
14
|
+
prefix: 'docker-exec',
|
|
15
|
+
ttl: 1000 * 60 * 3,
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
|
|
9
19
|
async function dockerExec({
|
|
10
20
|
blocklet,
|
|
11
21
|
meta,
|
|
@@ -15,7 +25,7 @@ async function dockerExec({
|
|
|
15
25
|
runScriptDir,
|
|
16
26
|
runScriptParams,
|
|
17
27
|
nodeInfo,
|
|
18
|
-
timeout =
|
|
28
|
+
timeout = 120_000,
|
|
19
29
|
retry = 3,
|
|
20
30
|
output,
|
|
21
31
|
error,
|
|
@@ -40,8 +50,13 @@ async function dockerExec({
|
|
|
40
50
|
await fs.writeFile(paramsFilePath, JSON.stringify(runScriptParams));
|
|
41
51
|
}
|
|
42
52
|
|
|
43
|
-
const
|
|
53
|
+
const lockKey = `${blockletDid}-${meta.name}-${hookName}`;
|
|
54
|
+
if (!(await lock.hasExpired(lockKey))) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
await lock.acquire(lockKey);
|
|
44
58
|
|
|
59
|
+
const command = `sh -c 'cd $BLOCKLET_APP_DIR && ${script}'`;
|
|
45
60
|
const options = await parseDockerOptionsFromPm2({
|
|
46
61
|
options: {
|
|
47
62
|
name: `${blockletDid}-${meta.name}-${hookName}`,
|
|
@@ -54,6 +69,7 @@ async function dockerExec({
|
|
|
54
69
|
dockerNamePrefix: 'docker-exec',
|
|
55
70
|
eventName: hookName,
|
|
56
71
|
});
|
|
72
|
+
|
|
57
73
|
const startTime = Date.now();
|
|
58
74
|
try {
|
|
59
75
|
await promiseSpawn(
|
|
@@ -65,12 +81,9 @@ async function dockerExec({
|
|
|
65
81
|
{ timeout, retry }
|
|
66
82
|
);
|
|
67
83
|
} finally {
|
|
84
|
+
await lock.releaseLock(lockKey);
|
|
68
85
|
if (nodeInfo.isDockerInstalled) {
|
|
69
|
-
await promiseSpawn(
|
|
70
|
-
`docker rm -fv ${options.env.dockerName} > /dev/null 2>&1 || true`,
|
|
71
|
-
{},
|
|
72
|
-
{ timeout: 1000 * 10, retry: 3 }
|
|
73
|
-
);
|
|
86
|
+
await promiseSpawn(`docker rm -f ${options.env.dockerName} > /dev/null 2>&1 || true`, {}, { timeout: 1000 * 10 });
|
|
74
87
|
}
|
|
75
88
|
}
|
|
76
89
|
logger.info(`dockerExec ${options.env.dockerName} cost time: ${Date.now() - startTime}ms`);
|
|
@@ -334,13 +334,8 @@ async function parseDockerOptionsFromPm2({
|
|
|
334
334
|
user = `-u ${uid}:${gid}`;
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
try {
|
|
338
|
-
await promiseSpawn(`docker rm -f ${name}`, { mute: true }, { timeout: 5 * 1000, retry: 0 });
|
|
339
|
-
} catch (_) {
|
|
340
|
-
// ignore error
|
|
341
|
-
}
|
|
342
|
-
|
|
343
337
|
nextOptions.script = `
|
|
338
|
+
docker rm -f ${name} > /dev/null 2>&1 || true && \
|
|
344
339
|
docker run --rm --name ${name} \
|
|
345
340
|
${user} \
|
|
346
341
|
${volumes} \
|
|
@@ -350,7 +345,6 @@ async function parseDockerOptionsFromPm2({
|
|
|
350
345
|
--cpus="${dockerEnv.BLOCKLET_DOCKER_CPUS}" \
|
|
351
346
|
--memory="${dockerEnv.BLOCKLET_DOCKER_MEMORY}" \
|
|
352
347
|
--memory-swap="${dockerEnv.BLOCKLET_DOCKER_MEMORY}" \
|
|
353
|
-
--memory-swappiness=0 \
|
|
354
348
|
--oom-kill-disable=false \
|
|
355
349
|
--env-file ${dockerEnvFile} \
|
|
356
350
|
${dockerInfo.network} \
|
package/lib/util/ensure-bun.js
CHANGED
|
@@ -36,7 +36,7 @@ async function _ensureBun() {
|
|
|
36
36
|
// 如果有 bun 且版本大于等于 BUN_VERSION, 则直接使用现有的 bun
|
|
37
37
|
if (whichBun) {
|
|
38
38
|
// 检查 bun 版本
|
|
39
|
-
const bunVersion = shelljs.exec(`${whichBun} --version
|
|
39
|
+
const bunVersion = shelljs.exec(`${whichBun} --version`, { silent: true }).stdout.trim();
|
|
40
40
|
// 判断 bun 版本是否大于等于 BUN_VERSION, 应该用版本对比库
|
|
41
41
|
if (semver.gte(bunVersion, BUN_VERSION)) {
|
|
42
42
|
return whichBun.toString();
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.47
|
|
6
|
+
"version": "1.16.47",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,23 +19,23 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@abtnode/analytics": "1.16.47
|
|
23
|
-
"@abtnode/auth": "1.16.47
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.47
|
|
25
|
-
"@abtnode/client": "1.16.47
|
|
26
|
-
"@abtnode/constant": "1.16.47
|
|
27
|
-
"@abtnode/cron": "1.16.47
|
|
28
|
-
"@abtnode/db-cache": "1.16.47
|
|
29
|
-
"@abtnode/docker-utils": "1.16.47
|
|
30
|
-
"@abtnode/logger": "1.16.47
|
|
31
|
-
"@abtnode/models": "1.16.47
|
|
32
|
-
"@abtnode/queue": "1.16.47
|
|
33
|
-
"@abtnode/rbac": "1.16.47
|
|
34
|
-
"@abtnode/router-provider": "1.16.47
|
|
35
|
-
"@abtnode/static-server": "1.16.47
|
|
36
|
-
"@abtnode/timemachine": "1.16.47
|
|
37
|
-
"@abtnode/util": "1.16.47
|
|
38
|
-
"@aigne/aigne-hub": "^0.4.
|
|
22
|
+
"@abtnode/analytics": "1.16.47",
|
|
23
|
+
"@abtnode/auth": "1.16.47",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.47",
|
|
25
|
+
"@abtnode/client": "1.16.47",
|
|
26
|
+
"@abtnode/constant": "1.16.47",
|
|
27
|
+
"@abtnode/cron": "1.16.47",
|
|
28
|
+
"@abtnode/db-cache": "1.16.47",
|
|
29
|
+
"@abtnode/docker-utils": "1.16.47",
|
|
30
|
+
"@abtnode/logger": "1.16.47",
|
|
31
|
+
"@abtnode/models": "1.16.47",
|
|
32
|
+
"@abtnode/queue": "1.16.47",
|
|
33
|
+
"@abtnode/rbac": "1.16.47",
|
|
34
|
+
"@abtnode/router-provider": "1.16.47",
|
|
35
|
+
"@abtnode/static-server": "1.16.47",
|
|
36
|
+
"@abtnode/timemachine": "1.16.47",
|
|
37
|
+
"@abtnode/util": "1.16.47",
|
|
38
|
+
"@aigne/aigne-hub": "^0.4.6",
|
|
39
39
|
"@arcblock/did": "1.21.2",
|
|
40
40
|
"@arcblock/did-connect-js": "1.21.2",
|
|
41
41
|
"@arcblock/did-ext": "1.21.2",
|
|
@@ -46,15 +46,15 @@
|
|
|
46
46
|
"@arcblock/pm2-events": "^0.0.5",
|
|
47
47
|
"@arcblock/validator": "1.21.2",
|
|
48
48
|
"@arcblock/vc": "1.21.2",
|
|
49
|
-
"@blocklet/constant": "1.16.47
|
|
50
|
-
"@blocklet/did-space-js": "^1.1.
|
|
51
|
-
"@blocklet/env": "1.16.47
|
|
49
|
+
"@blocklet/constant": "1.16.47",
|
|
50
|
+
"@blocklet/did-space-js": "^1.1.14",
|
|
51
|
+
"@blocklet/env": "1.16.47",
|
|
52
52
|
"@blocklet/error": "^0.2.5",
|
|
53
|
-
"@blocklet/meta": "1.16.47
|
|
54
|
-
"@blocklet/resolver": "1.16.47
|
|
55
|
-
"@blocklet/sdk": "1.16.47
|
|
56
|
-
"@blocklet/store": "1.16.47
|
|
57
|
-
"@blocklet/theme": "^3.
|
|
53
|
+
"@blocklet/meta": "1.16.47",
|
|
54
|
+
"@blocklet/resolver": "1.16.47",
|
|
55
|
+
"@blocklet/sdk": "1.16.47",
|
|
56
|
+
"@blocklet/store": "1.16.47",
|
|
57
|
+
"@blocklet/theme": "^3.1.3",
|
|
58
58
|
"@fidm/x509": "^1.2.1",
|
|
59
59
|
"@ocap/mcrypto": "1.21.2",
|
|
60
60
|
"@ocap/util": "1.21.2",
|
|
@@ -118,5 +118,5 @@
|
|
|
118
118
|
"jest": "^29.7.0",
|
|
119
119
|
"unzipper": "^0.10.11"
|
|
120
120
|
},
|
|
121
|
-
"gitHead": "
|
|
121
|
+
"gitHead": "02eecfdabe8acf7a10b0cc897958667777d64f79"
|
|
122
122
|
}
|