@abtnode/core 1.16.29-next-680cf137 → 1.16.30-beta-00e8bdd1
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/hooks.js +2 -0
- package/lib/blocklet/manager/disk.js +44 -46
- package/lib/blocklet/manager/helper/install-component-from-dev.js +4 -1
- package/lib/blocklet/manager/helper/upgrade-components.js +16 -10
- package/lib/blocklet/migration.js +4 -0
- package/lib/blocklet/project/publish-to-store.js +41 -8
- package/lib/crons/monitor-disk-usage.js +2 -2
- package/lib/event/index.js +1 -5
- package/lib/states/project.js +2 -0
- package/lib/util/blocklet.js +45 -7
- package/lib/util/index.js +2 -1
- package/package.json +34 -34
package/lib/blocklet/hooks.js
CHANGED
|
@@ -18,6 +18,7 @@ const runUserHook = async (label, hookName, args) => {
|
|
|
18
18
|
silent = false,
|
|
19
19
|
notification,
|
|
20
20
|
did,
|
|
21
|
+
timeout,
|
|
21
22
|
output: outputFile,
|
|
22
23
|
error: errorFile,
|
|
23
24
|
} = args;
|
|
@@ -40,6 +41,7 @@ const runUserHook = async (label, hookName, args) => {
|
|
|
40
41
|
NODE_OPTIONS: getSecurityNodeOptions({ environmentObj: env, ...args }, nodeInfo.enableFileSystemIsolation),
|
|
41
42
|
},
|
|
42
43
|
silent,
|
|
44
|
+
timeout,
|
|
43
45
|
output: outputFile,
|
|
44
46
|
error: errorFile,
|
|
45
47
|
});
|
|
@@ -212,9 +212,10 @@ const { formatEnvironments, getBlockletMeta, validateOwner, isCLI } = util;
|
|
|
212
212
|
|
|
213
213
|
const statusLock = new Lock('blocklet-status-lock');
|
|
214
214
|
|
|
215
|
-
const
|
|
215
|
+
const getHookArgs = (blocklet) => ({
|
|
216
216
|
output: blocklet.mode === BLOCKLET_MODES.DEVELOPMENT ? '' : path.join(blocklet.env.logsDir, 'output.log'),
|
|
217
217
|
error: blocklet.mode === BLOCKLET_MODES.DEVELOPMENT ? '' : path.join(blocklet.env.logsDir, 'error.log'),
|
|
218
|
+
timeout: (get(blocklet, 'meta.timeout.script') || 120) * 1000,
|
|
218
219
|
});
|
|
219
220
|
|
|
220
221
|
const pm2StatusMap = {
|
|
@@ -766,7 +767,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
766
767
|
hooks: Object.assign(b.meta.hooks || {}, b.meta.scripts || {}),
|
|
767
768
|
env,
|
|
768
769
|
did, // root blocklet did,
|
|
769
|
-
...
|
|
770
|
+
...getHookArgs(b),
|
|
770
771
|
});
|
|
771
772
|
|
|
772
773
|
// start process
|
|
@@ -867,7 +868,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
867
868
|
context,
|
|
868
869
|
exitOnError: false,
|
|
869
870
|
silent,
|
|
870
|
-
...
|
|
871
|
+
...getHookArgs(b),
|
|
871
872
|
}),
|
|
872
873
|
componentDids,
|
|
873
874
|
});
|
|
@@ -898,11 +899,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
898
899
|
? componentDids.map((x) => ({ did: x }))
|
|
899
900
|
: blocklet.children.map((x) => ({ did: x.meta.did })),
|
|
900
901
|
});
|
|
901
|
-
// for backward compatibility
|
|
902
|
-
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
903
|
-
appDid: blocklet.appDid,
|
|
904
|
-
components: getComponentsInternalInfo(res),
|
|
905
|
-
});
|
|
906
902
|
this.configSynchronizer.throttledSyncAppConfig(blocklet.meta.did);
|
|
907
903
|
|
|
908
904
|
let description = `${
|
|
@@ -1068,7 +1064,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1068
1064
|
notification: states.notification,
|
|
1069
1065
|
context,
|
|
1070
1066
|
exitOnError: false,
|
|
1071
|
-
...
|
|
1067
|
+
...getHookArgs(b),
|
|
1072
1068
|
}),
|
|
1073
1069
|
});
|
|
1074
1070
|
|
|
@@ -1265,11 +1261,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1265
1261
|
appDid: app.appDid,
|
|
1266
1262
|
components: [{ did: child.meta.did }],
|
|
1267
1263
|
});
|
|
1268
|
-
// for backward compatibility
|
|
1269
|
-
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
1270
|
-
appDid: app.appDid,
|
|
1271
|
-
components: getComponentsInternalInfo(newBlocklet),
|
|
1272
|
-
});
|
|
1273
1264
|
this.configSynchronizer.throttledSyncAppConfig(app.meta.did);
|
|
1274
1265
|
|
|
1275
1266
|
return { ...newBlocklet, deletedComponent: child };
|
|
@@ -1349,21 +1340,38 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1349
1340
|
}
|
|
1350
1341
|
}
|
|
1351
1342
|
|
|
1352
|
-
|
|
1353
|
-
|
|
1343
|
+
/**
|
|
1344
|
+
*
|
|
1345
|
+
* @param {object} param - params
|
|
1346
|
+
* @param {string} param.did - blocklet did
|
|
1347
|
+
* @param {string[]} param.componentDids - component dids
|
|
1348
|
+
* @param {boolean} param.shouldUpdateBlockletStatus - should update blocklet status
|
|
1349
|
+
* @param {*} context
|
|
1350
|
+
* @returns
|
|
1351
|
+
*/
|
|
1352
|
+
async deleteProcess({ did, componentDids, shouldUpdateBlockletStatus = true }, context) {
|
|
1354
1353
|
const blocklet = await this.getBlocklet(did);
|
|
1355
1354
|
|
|
1356
1355
|
logger.info('delete blocklet process', { did, componentDids });
|
|
1357
1356
|
|
|
1358
1357
|
await deleteBlockletProcess(blocklet, { ...context, componentDids });
|
|
1359
|
-
|
|
1360
|
-
const result = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, { componentDids });
|
|
1361
1358
|
logger.info('blocklet process deleted successfully', { did, componentDids });
|
|
1362
|
-
|
|
1359
|
+
|
|
1360
|
+
// 有些情况不需要更新 blocklet 状态, 比如下载完成,安装之前清理 process 时, 不需要更新 blocklet 状态
|
|
1361
|
+
if (shouldUpdateBlockletStatus) {
|
|
1362
|
+
const result = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, { componentDids });
|
|
1363
|
+
logger.info('blocklet status updated to stopped after deleted processes', { did, componentDids });
|
|
1364
|
+
return result;
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
return blocklet;
|
|
1363
1368
|
}
|
|
1364
1369
|
|
|
1365
1370
|
// Get blocklet by blockletDid or appDid
|
|
1366
|
-
async detail(
|
|
1371
|
+
async detail(
|
|
1372
|
+
{ did, attachConfig = true, attachRuntimeInfo, attachDiskInfo = false, useCache, getOptionalComponents },
|
|
1373
|
+
context
|
|
1374
|
+
) {
|
|
1367
1375
|
if (!did) {
|
|
1368
1376
|
throw new Error('did should not be empty');
|
|
1369
1377
|
}
|
|
@@ -1373,7 +1381,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1373
1381
|
}
|
|
1374
1382
|
|
|
1375
1383
|
if (attachRuntimeInfo) {
|
|
1376
|
-
return this._attachRuntimeInfo({ did, diskInfo:
|
|
1384
|
+
return this._attachRuntimeInfo({ did, diskInfo: !!attachDiskInfo, context, getOptionalComponents });
|
|
1377
1385
|
}
|
|
1378
1386
|
|
|
1379
1387
|
if (useCache && this.cachedBlocklets.has(did)) {
|
|
@@ -1490,7 +1498,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1490
1498
|
env: { ...getRuntimeEnvironments(blocklet, nodeEnvironments, ancestors), ...configObj },
|
|
1491
1499
|
did,
|
|
1492
1500
|
context,
|
|
1493
|
-
...
|
|
1501
|
+
...getHookArgs(blocklet),
|
|
1494
1502
|
});
|
|
1495
1503
|
}
|
|
1496
1504
|
|
|
@@ -1566,7 +1574,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1566
1574
|
this.configSynchronizer.throttledSyncAppConfig(blocklet.meta.did);
|
|
1567
1575
|
}
|
|
1568
1576
|
|
|
1569
|
-
this.emit(BlockletEvents.updated, { ...newState, context });
|
|
1570
1577
|
const serverSk = (await states.node.read()).sk;
|
|
1571
1578
|
if (childDid) {
|
|
1572
1579
|
const configs = JSON.stringify(finalConfigs.map((x) => ({ key: x.key, value: x.value })));
|
|
@@ -1579,6 +1586,8 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1579
1586
|
this.configSynchronizer.syncComponentConfig(childDid, rootDid, { serverSk });
|
|
1580
1587
|
}
|
|
1581
1588
|
|
|
1589
|
+
this.emit(BlockletEvents.updated, { ...newState, context });
|
|
1590
|
+
|
|
1582
1591
|
try {
|
|
1583
1592
|
const observableConfigs = [
|
|
1584
1593
|
BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_URL,
|
|
@@ -1853,11 +1862,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1853
1862
|
appDid: blocklet.appDid,
|
|
1854
1863
|
components: getComponentsInternalInfo(blocklet).filter((x) => x.did === component.meta.did),
|
|
1855
1864
|
});
|
|
1856
|
-
// for backward compatibility
|
|
1857
|
-
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
1858
|
-
appDid: blocklet.appDid,
|
|
1859
|
-
components: getComponentsInternalInfo(blocklet),
|
|
1860
|
-
});
|
|
1861
1865
|
this.configSynchronizer.throttledSyncAppConfig(blocklet.meta.did);
|
|
1862
1866
|
|
|
1863
1867
|
return this.getBlocklet(rootDid);
|
|
@@ -2709,11 +2713,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
2709
2713
|
appDid: blocklet.appDid,
|
|
2710
2714
|
components: (componentDids || []).map((x) => ({ did: x })),
|
|
2711
2715
|
});
|
|
2712
|
-
// for backward compatibility
|
|
2713
|
-
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
2714
|
-
appDid: blocklet.appDid,
|
|
2715
|
-
components: getComponentsInternalInfo(res),
|
|
2716
|
-
});
|
|
2717
2716
|
this.configSynchronizer.throttledSyncAppConfig(res);
|
|
2718
2717
|
|
|
2719
2718
|
this.emit(BlockletEvents.statusChange, res);
|
|
@@ -3247,7 +3246,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3247
3246
|
return [];
|
|
3248
3247
|
}
|
|
3249
3248
|
|
|
3250
|
-
async _attachRuntimeInfo({ did, diskInfo =
|
|
3249
|
+
async _attachRuntimeInfo({ did, diskInfo = false, context, getOptionalComponents }) {
|
|
3251
3250
|
if (!did) {
|
|
3252
3251
|
throw new Error('did should not be empty');
|
|
3253
3252
|
}
|
|
@@ -3259,7 +3258,9 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3259
3258
|
return null;
|
|
3260
3259
|
}
|
|
3261
3260
|
|
|
3262
|
-
blocklet.site
|
|
3261
|
+
if (blocklet.site) {
|
|
3262
|
+
blocklet.site.domainAliases = await this.getDomainAliases(blocklet, context);
|
|
3263
|
+
}
|
|
3263
3264
|
|
|
3264
3265
|
// app runtime info, app status
|
|
3265
3266
|
blocklet.appRuntimeInfo = this.runtimeMonitor.getRuntimeInfo(blocklet.meta.did);
|
|
@@ -3449,7 +3450,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3449
3450
|
|
|
3450
3451
|
// ensure delete process
|
|
3451
3452
|
try {
|
|
3452
|
-
await this.deleteProcess({ did }, context);
|
|
3453
|
+
await this.deleteProcess({ did, shouldUpdateBlockletStatus: false }, context);
|
|
3453
3454
|
logger.info('ensure delete blocklet process for installing', { did, name: meta.name });
|
|
3454
3455
|
} catch (err) {
|
|
3455
3456
|
logger.error('ensure delete blocklet process failed for installing', { did, name: meta.name, error: err });
|
|
@@ -3642,7 +3643,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3642
3643
|
env: getRuntimeEnvironments(b, nodeEnvironments, [blocklet]),
|
|
3643
3644
|
oldVersion: oldVersions[b.meta.did],
|
|
3644
3645
|
newVersion: b.meta.version,
|
|
3645
|
-
...
|
|
3646
|
+
...getHookArgs(b),
|
|
3646
3647
|
});
|
|
3647
3648
|
} catch (error) {
|
|
3648
3649
|
logger.error('Failed to run migration scripts', { appDid: did, title: b.meta.title, error });
|
|
@@ -3693,7 +3694,8 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3693
3694
|
}
|
|
3694
3695
|
}
|
|
3695
3696
|
if (stoppedDids.length) {
|
|
3696
|
-
|
|
3697
|
+
const status = action === INSTALL_ACTIONS.INSTALL_COMPONENT ? BlockletStatus.installed : BlockletStatus.stopped;
|
|
3698
|
+
await states.blocklet.setBlockletStatus(did, status, { componentDids: stoppedDids });
|
|
3697
3699
|
}
|
|
3698
3700
|
|
|
3699
3701
|
blocklet = await this.getBlocklet(did, context);
|
|
@@ -3747,11 +3749,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3747
3749
|
}
|
|
3748
3750
|
);
|
|
3749
3751
|
}
|
|
3750
|
-
// for backward compatibility
|
|
3751
|
-
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
3752
|
-
appDid: blocklet.appDid,
|
|
3753
|
-
components: getComponentsInternalInfo(blocklet),
|
|
3754
|
-
});
|
|
3755
3752
|
this.configSynchronizer.throttledSyncAppConfig(blocklet);
|
|
3756
3753
|
|
|
3757
3754
|
return blocklet;
|
|
@@ -4040,7 +4037,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
4040
4037
|
did: blocklet.meta.did, // root blocklet did
|
|
4041
4038
|
notification: states.notification,
|
|
4042
4039
|
context,
|
|
4043
|
-
...
|
|
4040
|
+
...getHookArgs(b),
|
|
4044
4041
|
});
|
|
4045
4042
|
|
|
4046
4043
|
await forEachBlocklet(blocklet, hookFn, { parallel: true, concurrencyLimit: 4 });
|
|
@@ -4210,14 +4207,15 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
4210
4207
|
for (const data of blockletExtras) {
|
|
4211
4208
|
try {
|
|
4212
4209
|
const { did } = data;
|
|
4213
|
-
const launcherSession = await launcher.getLauncherSession({
|
|
4210
|
+
const { launcherSession } = await launcher.getLauncherSession({
|
|
4214
4211
|
launcherUrl: data.controller.launcherUrl,
|
|
4215
4212
|
launcherSessionId: data.controller.launcherSessionId,
|
|
4216
4213
|
});
|
|
4214
|
+
|
|
4217
4215
|
const isTerminated = launcher.isLaunchSessionTerminated(launcherSession);
|
|
4218
4216
|
|
|
4219
4217
|
if (!isTerminated) {
|
|
4220
|
-
logger.info('skip cleaning the non-
|
|
4218
|
+
logger.info('skip cleaning the non-terminated blocklet', {
|
|
4221
4219
|
blockletDid: did,
|
|
4222
4220
|
controller: data.controller,
|
|
4223
4221
|
launcherSession,
|
|
@@ -13,7 +13,10 @@ const { formatName } = require('../../../util/get-domain-for-blocklet');
|
|
|
13
13
|
|
|
14
14
|
const needParseDependents = (meta, app) => {
|
|
15
15
|
const dependents = (meta.components || []).map((x) => x.source.name);
|
|
16
|
-
|
|
16
|
+
if (meta.engine?.interpreter === 'blocklet') {
|
|
17
|
+
dependents.push(meta.engine.source.name);
|
|
18
|
+
}
|
|
19
|
+
return !dependents.filter(Boolean).every((name) => app.children.some((x) => x.meta.name === name));
|
|
17
20
|
};
|
|
18
21
|
|
|
19
22
|
const installComponentFromDev = async ({ folder, meta, rootDid, mountPoint, manager, states, skipParseDependents }) => {
|
|
@@ -30,18 +30,24 @@ const check = async ({ did, states }) => {
|
|
|
30
30
|
const bundleSource = getFixedBundleSource(child);
|
|
31
31
|
|
|
32
32
|
if (bundleSource) {
|
|
33
|
-
const { dynamicComponents } = await parseComponents(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
const { dynamicComponents } = await parseComponents(
|
|
34
|
+
{
|
|
35
|
+
meta: {
|
|
36
|
+
components: [
|
|
37
|
+
{
|
|
38
|
+
source: bundleSource,
|
|
39
|
+
name: child.meta.name,
|
|
40
|
+
mountPoint: child.mountPoint,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
42
44
|
},
|
|
43
|
-
|
|
45
|
+
{ continueOnError: true }
|
|
46
|
+
);
|
|
44
47
|
const newChild = dynamicComponents.find((x) => x.meta.name === child.meta.name);
|
|
48
|
+
if (!newChild) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
45
51
|
newChild._dynamicComponents = dynamicComponents.filter((x) => x.meta.name !== child.meta.name);
|
|
46
52
|
newChildren.push(newChild);
|
|
47
53
|
} else {
|
|
@@ -22,6 +22,7 @@ async function runScripts({
|
|
|
22
22
|
printError,
|
|
23
23
|
output,
|
|
24
24
|
error,
|
|
25
|
+
timeout,
|
|
25
26
|
}) {
|
|
26
27
|
// 获取所有待执行的脚本
|
|
27
28
|
let scripts = [];
|
|
@@ -61,6 +62,7 @@ async function runScripts({
|
|
|
61
62
|
silent: false,
|
|
62
63
|
output,
|
|
63
64
|
error,
|
|
65
|
+
timeout,
|
|
64
66
|
});
|
|
65
67
|
printInfo(`Migration script executed: ${scriptPath}`);
|
|
66
68
|
} catch (migrationErr) {
|
|
@@ -107,6 +109,7 @@ module.exports = async ({
|
|
|
107
109
|
printError = logger.error,
|
|
108
110
|
output,
|
|
109
111
|
error,
|
|
112
|
+
timeout,
|
|
110
113
|
}) => {
|
|
111
114
|
if (!oldVersion) {
|
|
112
115
|
return;
|
|
@@ -136,6 +139,7 @@ module.exports = async ({
|
|
|
136
139
|
printSuccess,
|
|
137
140
|
output,
|
|
138
141
|
error,
|
|
142
|
+
timeout,
|
|
139
143
|
});
|
|
140
144
|
|
|
141
145
|
fs.removeSync(backupDir);
|
|
@@ -2,6 +2,7 @@ const path = require('path');
|
|
|
2
2
|
const { PROJECT } = require('@blocklet/constant');
|
|
3
3
|
const { upload } = require('@blocklet/store');
|
|
4
4
|
const { getDisplayName } = require('@blocklet/meta/lib/util');
|
|
5
|
+
const fs = require('fs/promises');
|
|
5
6
|
|
|
6
7
|
function ensureArray(value) {
|
|
7
8
|
if (!value) {
|
|
@@ -18,6 +19,37 @@ function getReleaseDir(blocklet, projectId, releaseId) {
|
|
|
18
19
|
return path.join(projectDir, PROJECT.RELEASE_DIR, `${releaseId}`);
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
const MAX_RETRIES = 5;
|
|
23
|
+
const RETRY_DELAY = 100;
|
|
24
|
+
|
|
25
|
+
// 利用乐观锁, 去更新字段, 如果连续5次都失败, 就算更新失败
|
|
26
|
+
async function updateReleaseWithRetry(releaseState, releaseId, projectId, storeId) {
|
|
27
|
+
// eslint-disable-next-line no-unused-vars
|
|
28
|
+
for (const _ of Array(MAX_RETRIES).fill(0)) {
|
|
29
|
+
// eslint-disable-next-line no-await-in-loop
|
|
30
|
+
const release = await releaseState.findOne({ projectId, id: releaseId });
|
|
31
|
+
release.publishedStoreIds = ensureArray(release.publishedStoreIds);
|
|
32
|
+
release.publishedStoreIds.push(storeId);
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
// eslint-disable-next-line no-await-in-loop
|
|
36
|
+
const result = await releaseState.update(
|
|
37
|
+
{ id: releaseId, updatedAt: release.updatedAt },
|
|
38
|
+
{ $set: { publishedStoreIds: Array.from(new Set(release.publishedStoreIds)) } }
|
|
39
|
+
);
|
|
40
|
+
if (result?.[0] > 0) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
// eslint-disable-next-line no-await-in-loop
|
|
44
|
+
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY));
|
|
45
|
+
} catch (error) {
|
|
46
|
+
throw new Error(`Failed to update release: ${error.message}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
throw new Error('Failed to update release after maximum retries');
|
|
51
|
+
}
|
|
52
|
+
|
|
21
53
|
const publishToStore = async ({ did, projectId, releaseId, type, storeId, manager }) => {
|
|
22
54
|
if (
|
|
23
55
|
!did ||
|
|
@@ -42,6 +74,7 @@ const publishToStore = async ({ did, projectId, releaseId, type, storeId, manage
|
|
|
42
74
|
if (!store) {
|
|
43
75
|
throw new Error('no find connected store');
|
|
44
76
|
}
|
|
77
|
+
|
|
45
78
|
const { storeUrl } = store;
|
|
46
79
|
const { accessToken, developerDid } = store;
|
|
47
80
|
|
|
@@ -50,7 +83,12 @@ const publishToStore = async ({ did, projectId, releaseId, type, storeId, manage
|
|
|
50
83
|
throw new Error('blocklet not found');
|
|
51
84
|
}
|
|
52
85
|
|
|
53
|
-
const
|
|
86
|
+
const project = await projectState.findOne({ id: projectId });
|
|
87
|
+
let releaseDir = getReleaseDir(blocklet, projectId, releaseId);
|
|
88
|
+
if (project.possibleSameStore) {
|
|
89
|
+
await fs.cp(releaseDir, `${releaseDir}-${storeId}`, { recursive: true });
|
|
90
|
+
releaseDir = `${releaseDir}-${storeId}`;
|
|
91
|
+
}
|
|
54
92
|
const metaFile = path.join(releaseDir, '.blocklet', 'release', 'blocklet.json');
|
|
55
93
|
|
|
56
94
|
const response = await upload({
|
|
@@ -58,16 +96,11 @@ const publishToStore = async ({ did, projectId, releaseId, type, storeId, manage
|
|
|
58
96
|
storeUrl,
|
|
59
97
|
accessToken,
|
|
60
98
|
developerDid,
|
|
99
|
+
possibleSameStore: project.possibleSameStore,
|
|
61
100
|
source: `Blocklet Studio (${getDisplayName(blocklet)})`,
|
|
62
101
|
});
|
|
63
102
|
|
|
64
|
-
|
|
65
|
-
release.publishedStoreIds.push(storeId);
|
|
66
|
-
|
|
67
|
-
await releaseState.update(
|
|
68
|
-
{ id: releaseId },
|
|
69
|
-
{ $set: { publishedStoreIds: Array.from(new Set(release.publishedStoreIds)) } }
|
|
70
|
-
);
|
|
103
|
+
await updateReleaseWithRetry(releaseState, releaseId, projectId, storeId);
|
|
71
104
|
|
|
72
105
|
return response?.status;
|
|
73
106
|
};
|
|
@@ -11,14 +11,14 @@ const check = async (threshold) => {
|
|
|
11
11
|
for (const disk of disks) {
|
|
12
12
|
const usageRatio = (disk.used / disk.total) * 100;
|
|
13
13
|
if (Number.isNaN(usageRatio)) {
|
|
14
|
-
|
|
14
|
+
continue;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const usageRatioPercent = `${usageRatio.toFixed(2)}%`;
|
|
18
18
|
logger.info('check disk usage', { usage: usageRatioPercent, threshold });
|
|
19
19
|
|
|
20
20
|
if (usageRatio < threshold) {
|
|
21
|
-
|
|
21
|
+
continue;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// eslint-disable-next-line no-await-in-loop
|
package/lib/event/index.js
CHANGED
|
@@ -357,11 +357,7 @@ module.exports = ({
|
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
-
if (
|
|
361
|
-
[BlockletEvents.started, BlockletEvents.startFailed, BlockletEvents.stopped, BlockletEvents.reloaded].includes(
|
|
362
|
-
eventName
|
|
363
|
-
)
|
|
364
|
-
) {
|
|
360
|
+
if ([BlockletEvents.started, BlockletEvents.startFailed, BlockletEvents.stopped].includes(eventName)) {
|
|
365
361
|
try {
|
|
366
362
|
await blockletManager.runtimeMonitor.monit(blocklet.meta.did);
|
|
367
363
|
} catch (error) {
|
package/lib/states/project.js
CHANGED
package/lib/util/blocklet.js
CHANGED
|
@@ -639,7 +639,13 @@ const startBlockletProcess = async (
|
|
|
639
639
|
const clusterSize = Number(blocklet.configObj.BLOCKLET_CLUSTER_SIZE) || +process.env.ABT_NODE_MAX_CLUSTER_SIZE;
|
|
640
640
|
options.execMode = 'cluster';
|
|
641
641
|
options.mergeLogs = true;
|
|
642
|
-
options.instances = Math.min(os.cpus().length, clusterSize);
|
|
642
|
+
options.instances = Math.max(Math.min(os.cpus().length, clusterSize), 1);
|
|
643
|
+
options.env.BLOCKLET_CLUSTER_SIZE = options.instances;
|
|
644
|
+
if (options.instances !== clusterSize) {
|
|
645
|
+
logger.warn(`Fallback cluster size to ${options.instances} for ${processId}, ignore custom ${clusterSize}`);
|
|
646
|
+
}
|
|
647
|
+
} else {
|
|
648
|
+
delete options.env.BLOCKLET_CLUSTER_SIZE;
|
|
643
649
|
}
|
|
644
650
|
|
|
645
651
|
if (b.mode === BLOCKLET_MODES.DEVELOPMENT) {
|
|
@@ -1069,11 +1075,8 @@ const pruneBlockletBundle = async ({ blocklets, installDir, blockletSettings })
|
|
|
1069
1075
|
logger.info('Blocklet source folder has been pruned');
|
|
1070
1076
|
};
|
|
1071
1077
|
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
return { app: 0, cache: 0, log: 0, data: 0 };
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1078
|
+
const _diskInfoTasks = {};
|
|
1079
|
+
const _getDiskInfo = async (blocklet) => {
|
|
1077
1080
|
try {
|
|
1078
1081
|
const { env } = blocklet;
|
|
1079
1082
|
const [app, cache, log, data] = await Promise.all([
|
|
@@ -1084,9 +1087,30 @@ const getDiskInfo = async (blocklet, { useFakeDiskInfo } = {}) => {
|
|
|
1084
1087
|
]);
|
|
1085
1088
|
return { app, cache, log, data };
|
|
1086
1089
|
} catch (error) {
|
|
1087
|
-
logger.error('Get disk info failed', { name: blocklet
|
|
1090
|
+
logger.error('Get disk info failed', { name: getDisplayName(blocklet), error });
|
|
1091
|
+
return { app: 0, cache: 0, log: 0, data: 0 };
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
|
|
1095
|
+
const getDiskInfo = (blocklet, { useFakeDiskInfo } = {}) => {
|
|
1096
|
+
if (useFakeDiskInfo) {
|
|
1088
1097
|
return { app: 0, cache: 0, log: 0, data: 0 };
|
|
1089
1098
|
}
|
|
1099
|
+
|
|
1100
|
+
const { appDid } = blocklet;
|
|
1101
|
+
|
|
1102
|
+
// Cache disk info results for 1 minute
|
|
1103
|
+
_diskInfoTasks[appDid] ??= _getDiskInfo(blocklet).finally(() => {
|
|
1104
|
+
setTimeout(() => {
|
|
1105
|
+
delete _diskInfoTasks[appDid];
|
|
1106
|
+
}, 120 * 1000);
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
return new Promise((resolve) => {
|
|
1110
|
+
_diskInfoTasks[appDid].then(resolve).catch(() => {
|
|
1111
|
+
resolve({ app: 0, cache: 0, log: 0, data: 0 });
|
|
1112
|
+
});
|
|
1113
|
+
});
|
|
1090
1114
|
};
|
|
1091
1115
|
|
|
1092
1116
|
const getRuntimeInfo = async (processId) => {
|
|
@@ -1579,6 +1603,20 @@ const validateAppConfig = async (config, states) => {
|
|
|
1579
1603
|
throw new Error(`${x.key}(${x.value}) is not a valid URL`);
|
|
1580
1604
|
}
|
|
1581
1605
|
}
|
|
1606
|
+
|
|
1607
|
+
if (x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_CLUSTER_SIZE) {
|
|
1608
|
+
if (isEmpty(x.value)) {
|
|
1609
|
+
x.value = '';
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
const v = Number(x.value);
|
|
1613
|
+
if (Number.isNaN(v)) {
|
|
1614
|
+
throw new Error(`${x.key} must be number`);
|
|
1615
|
+
}
|
|
1616
|
+
if (!Number.isInteger(v)) {
|
|
1617
|
+
throw new Error(`${x.key} must be integer`);
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1582
1620
|
};
|
|
1583
1621
|
|
|
1584
1622
|
const checkDuplicateAppSk = async ({ sk, did, states }) => {
|
package/lib/util/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const shell = require('shelljs');
|
|
|
7
7
|
const camelCase = require('lodash/camelCase');
|
|
8
8
|
const get = require('lodash/get');
|
|
9
9
|
const pickBy = require('lodash/pickBy');
|
|
10
|
+
const uniq = require('lodash/uniq');
|
|
10
11
|
const { isFromPublicKey } = require('@arcblock/did');
|
|
11
12
|
const { joinURL } = require('ufo');
|
|
12
13
|
const { Certificate } = require('@fidm/x509');
|
|
@@ -195,7 +196,7 @@ const getBaseUrls = async (node, ips) => {
|
|
|
195
196
|
const info = await node.getNodeInfo();
|
|
196
197
|
const { https, httpPort, httpsPort } = info.routing;
|
|
197
198
|
const getPort = (port, defaultPort) => (port && port !== defaultPort ? `:${port}` : '');
|
|
198
|
-
const availableIps = ips.filter(Boolean);
|
|
199
|
+
const availableIps = uniq(ips.filter(Boolean));
|
|
199
200
|
|
|
200
201
|
const getHttpInfo = async (domain) => {
|
|
201
202
|
const certificate = https ? await node.certManager.getNormalByDomain(domain) : null;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.
|
|
6
|
+
"version": "1.16.30-beta-00e8bdd1",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,40 +19,40 @@
|
|
|
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.
|
|
23
|
-
"@abtnode/auth": "1.16.
|
|
24
|
-
"@abtnode/certificate-manager": "1.16.
|
|
25
|
-
"@abtnode/constant": "1.16.
|
|
26
|
-
"@abtnode/cron": "1.16.
|
|
27
|
-
"@abtnode/logger": "1.16.
|
|
28
|
-
"@abtnode/models": "1.16.
|
|
29
|
-
"@abtnode/queue": "1.16.
|
|
30
|
-
"@abtnode/rbac": "1.16.
|
|
31
|
-
"@abtnode/router-provider": "1.16.
|
|
32
|
-
"@abtnode/static-server": "1.16.
|
|
33
|
-
"@abtnode/timemachine": "1.16.
|
|
34
|
-
"@abtnode/util": "1.16.
|
|
35
|
-
"@arcblock/did": "1.18.
|
|
36
|
-
"@arcblock/did-auth": "1.18.
|
|
37
|
-
"@arcblock/did-ext": "^1.18.
|
|
22
|
+
"@abtnode/analytics": "1.16.30-beta-00e8bdd1",
|
|
23
|
+
"@abtnode/auth": "1.16.30-beta-00e8bdd1",
|
|
24
|
+
"@abtnode/certificate-manager": "1.16.30-beta-00e8bdd1",
|
|
25
|
+
"@abtnode/constant": "1.16.30-beta-00e8bdd1",
|
|
26
|
+
"@abtnode/cron": "1.16.30-beta-00e8bdd1",
|
|
27
|
+
"@abtnode/logger": "1.16.30-beta-00e8bdd1",
|
|
28
|
+
"@abtnode/models": "1.16.30-beta-00e8bdd1",
|
|
29
|
+
"@abtnode/queue": "1.16.30-beta-00e8bdd1",
|
|
30
|
+
"@abtnode/rbac": "1.16.30-beta-00e8bdd1",
|
|
31
|
+
"@abtnode/router-provider": "1.16.30-beta-00e8bdd1",
|
|
32
|
+
"@abtnode/static-server": "1.16.30-beta-00e8bdd1",
|
|
33
|
+
"@abtnode/timemachine": "1.16.30-beta-00e8bdd1",
|
|
34
|
+
"@abtnode/util": "1.16.30-beta-00e8bdd1",
|
|
35
|
+
"@arcblock/did": "1.18.128",
|
|
36
|
+
"@arcblock/did-auth": "1.18.128",
|
|
37
|
+
"@arcblock/did-ext": "^1.18.128",
|
|
38
38
|
"@arcblock/did-motif": "^1.1.13",
|
|
39
|
-
"@arcblock/did-util": "1.18.
|
|
40
|
-
"@arcblock/event-hub": "1.18.
|
|
41
|
-
"@arcblock/jwt": "^1.18.
|
|
39
|
+
"@arcblock/did-util": "1.18.128",
|
|
40
|
+
"@arcblock/event-hub": "1.18.128",
|
|
41
|
+
"@arcblock/jwt": "^1.18.128",
|
|
42
42
|
"@arcblock/pm2-events": "^0.0.5",
|
|
43
|
-
"@arcblock/validator": "^1.18.
|
|
44
|
-
"@arcblock/vc": "1.18.
|
|
45
|
-
"@blocklet/constant": "1.16.
|
|
46
|
-
"@blocklet/env": "1.16.
|
|
47
|
-
"@blocklet/meta": "1.16.
|
|
48
|
-
"@blocklet/resolver": "1.16.
|
|
49
|
-
"@blocklet/sdk": "1.16.
|
|
50
|
-
"@blocklet/store": "1.16.
|
|
51
|
-
"@did-space/client": "^0.5.
|
|
43
|
+
"@arcblock/validator": "^1.18.128",
|
|
44
|
+
"@arcblock/vc": "1.18.128",
|
|
45
|
+
"@blocklet/constant": "1.16.30-beta-00e8bdd1",
|
|
46
|
+
"@blocklet/env": "1.16.30-beta-00e8bdd1",
|
|
47
|
+
"@blocklet/meta": "1.16.30-beta-00e8bdd1",
|
|
48
|
+
"@blocklet/resolver": "1.16.30-beta-00e8bdd1",
|
|
49
|
+
"@blocklet/sdk": "1.16.30-beta-00e8bdd1",
|
|
50
|
+
"@blocklet/store": "1.16.30-beta-00e8bdd1",
|
|
51
|
+
"@did-space/client": "^0.5.17",
|
|
52
52
|
"@fidm/x509": "^1.2.1",
|
|
53
|
-
"@ocap/mcrypto": "1.18.
|
|
54
|
-
"@ocap/util": "1.18.
|
|
55
|
-
"@ocap/wallet": "1.18.
|
|
53
|
+
"@ocap/mcrypto": "1.18.128",
|
|
54
|
+
"@ocap/util": "1.18.128",
|
|
55
|
+
"@ocap/wallet": "1.18.128",
|
|
56
56
|
"@slack/webhook": "^5.0.4",
|
|
57
57
|
"archiver": "^7.0.1",
|
|
58
58
|
"axios": "^1.7.2",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"ssri": "^8.0.1",
|
|
88
88
|
"stream-throttle": "^0.1.3",
|
|
89
89
|
"stream-to-promise": "^3.0.0",
|
|
90
|
-
"systeminformation": "^5.
|
|
90
|
+
"systeminformation": "^5.23.3",
|
|
91
91
|
"tail": "^2.2.4",
|
|
92
92
|
"tar": "^6.1.11",
|
|
93
93
|
"transliteration": "^2.3.5",
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"jest": "^29.7.0",
|
|
104
104
|
"unzipper": "^0.10.11"
|
|
105
105
|
},
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "e165c7e64a2900b4c390b7435c0bb71abbf9b625"
|
|
107
107
|
}
|