@abtnode/core 1.16.11-next-a232f5fb → 1.16.11-next-09bc31f8
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/downloader/blocklet-downloader.js +3 -3
- package/lib/blocklet/manager/disk.js +212 -128
- package/lib/blocklet/manager/helper/install-component-from-dev.js +0 -1
- package/lib/blocklet/manager/helper/install-component-from-upload.js +8 -4
- package/lib/blocklet/manager/helper/install-component-from-url.js +4 -2
- package/lib/blocklet/manager/helper/upgrade-components.js +7 -7
- package/lib/blocklet/manager/pm2-events.js +3 -3
- package/lib/event.js +11 -1
- package/lib/index.js +0 -1
- package/lib/migrations/1.16.11-component-status.js +22 -0
- package/lib/monitor/blocklet-runtime-monitor.js +7 -2
- package/lib/states/blocklet.js +45 -38
- package/lib/states/node.js +1 -0
- package/lib/util/blocklet.js +114 -61
- package/package.json +17 -17
|
@@ -38,6 +38,10 @@ const {
|
|
|
38
38
|
getRolesFromAuthConfig,
|
|
39
39
|
isInProgress,
|
|
40
40
|
isBeforeInstalled,
|
|
41
|
+
getComponentsInternalInfo,
|
|
42
|
+
forEachComponentV2,
|
|
43
|
+
forEachComponentV2Sync,
|
|
44
|
+
findComponentByIdV2,
|
|
41
45
|
} = require('@blocklet/meta/lib/util');
|
|
42
46
|
const getComponentProcessId = require('@blocklet/meta/lib/get-component-process-id');
|
|
43
47
|
const { update: updateMetaFile } = require('@blocklet/meta/lib/file');
|
|
@@ -49,6 +53,7 @@ const {
|
|
|
49
53
|
BlockletStatus,
|
|
50
54
|
BlockletSource,
|
|
51
55
|
BlockletEvents,
|
|
56
|
+
BlockletInternalEvents,
|
|
52
57
|
BLOCKLET_MODES,
|
|
53
58
|
BlockletGroup,
|
|
54
59
|
fromBlockletStatus,
|
|
@@ -81,7 +86,6 @@ const {
|
|
|
81
86
|
stopBlockletProcess,
|
|
82
87
|
deleteBlockletProcess,
|
|
83
88
|
reloadBlockletProcess,
|
|
84
|
-
getBlockletStatusFromProcess,
|
|
85
89
|
checkBlockletProcessHealthy,
|
|
86
90
|
validateBlocklet,
|
|
87
91
|
validateBlockletChainInfo,
|
|
@@ -104,6 +108,9 @@ const {
|
|
|
104
108
|
updateBlockletFallbackLogo,
|
|
105
109
|
ensureAppLogo,
|
|
106
110
|
getBlockletDidDomainList,
|
|
111
|
+
getProcessState,
|
|
112
|
+
getBlockletStatus,
|
|
113
|
+
shouldSkipComponent,
|
|
107
114
|
shouldCleanExpiredBlocklet,
|
|
108
115
|
} = require('../../util/blocklet');
|
|
109
116
|
const states = require('../../states');
|
|
@@ -133,7 +140,7 @@ const { migrateApplicationToStructV2 } = require('./helper/migrate-application-t
|
|
|
133
140
|
const { getBackupFilesUrlFromEndpoint, getBackupEndpoint } = require('../../util/spaces');
|
|
134
141
|
const { validateAddSpaceGateway, validateUpdateSpaceGateway } = require('../../validators/space-gateway');
|
|
135
142
|
|
|
136
|
-
const { formatEnvironments,
|
|
143
|
+
const { formatEnvironments, getBlockletMeta, validateOwner } = util;
|
|
137
144
|
|
|
138
145
|
const statusLock = new Lock('blocklet-status-lock');
|
|
139
146
|
|
|
@@ -239,8 +246,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
239
246
|
this._rollbackCache = new RollbackCache({ dir: this.dataDirs.tmp });
|
|
240
247
|
|
|
241
248
|
if (daemon) {
|
|
242
|
-
blockletPm2Events.on('online', (data) => this._syncPm2Status('online', data.blockletDid));
|
|
243
|
-
blockletPm2Events.on('stop', (data) => this._syncPm2Status('stop', data.blockletDid));
|
|
249
|
+
blockletPm2Events.on('online', (data) => this._syncPm2Status('online', data.blockletDid, data.componentDid));
|
|
250
|
+
blockletPm2Events.on('stop', (data) => this._syncPm2Status('stop', data.blockletDid, data.componentDid));
|
|
244
251
|
}
|
|
245
252
|
}
|
|
246
253
|
|
|
@@ -427,8 +434,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
427
434
|
return UpgradeComponents.check({ did, states });
|
|
428
435
|
}
|
|
429
436
|
|
|
430
|
-
async upgradeComponents({ updateId, selectedComponents:
|
|
431
|
-
return UpgradeComponents.upgrade({ updateId,
|
|
437
|
+
async upgradeComponents({ updateId, selectedComponents: componentDids }, context = {}) {
|
|
438
|
+
return UpgradeComponents.upgrade({ updateId, componentDids, context, states, manager: this });
|
|
432
439
|
}
|
|
433
440
|
|
|
434
441
|
async migrateApplicationToStructV2({ did, appSk, context = {} }) {
|
|
@@ -445,8 +452,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
445
452
|
return { did, isInstalled: !!blocklet, isRunning };
|
|
446
453
|
}
|
|
447
454
|
|
|
448
|
-
async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false }, context) {
|
|
449
|
-
logger.info('start blocklet', { did });
|
|
455
|
+
async start({ did, throwOnError, checkHealthImmediately = false, e2eMode = false, componentDids }, context) {
|
|
456
|
+
logger.info('start blocklet', { did, componentDids, throwOnError, checkHealthImmediately, e2eMode });
|
|
450
457
|
// should check blocklet integrity
|
|
451
458
|
const blocklet = await this.ensureBlocklet(did, { e2eMode });
|
|
452
459
|
|
|
@@ -454,7 +461,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
454
461
|
// blocklet may be manually stopped durning starting
|
|
455
462
|
// so error message would not be sent if blocklet is stopped
|
|
456
463
|
// so we need update status first
|
|
457
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.starting);
|
|
464
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.starting, { componentDids });
|
|
458
465
|
blocklet.status = BlockletStatus.starting;
|
|
459
466
|
|
|
460
467
|
// validate requirement and engine
|
|
@@ -507,6 +514,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
507
514
|
nodeEnvironments,
|
|
508
515
|
nodeInfo: await states.node.read(),
|
|
509
516
|
e2eMode,
|
|
517
|
+
componentDids,
|
|
510
518
|
});
|
|
511
519
|
|
|
512
520
|
// check blocklet healthy
|
|
@@ -516,6 +524,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
516
524
|
context,
|
|
517
525
|
minConsecutiveTime,
|
|
518
526
|
timeout: startTimeout,
|
|
527
|
+
componentDids,
|
|
519
528
|
};
|
|
520
529
|
|
|
521
530
|
if (checkHealthImmediately) {
|
|
@@ -548,8 +557,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
548
557
|
severity: 'error',
|
|
549
558
|
});
|
|
550
559
|
|
|
551
|
-
await this.deleteProcess({ did });
|
|
552
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error);
|
|
560
|
+
await this.deleteProcess({ did, componentDids });
|
|
561
|
+
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
553
562
|
this.emit(BlockletEvents.startFailed, { ...res, error: { message: error.message } });
|
|
554
563
|
|
|
555
564
|
if (throwOnError) {
|
|
@@ -560,14 +569,14 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
560
569
|
}
|
|
561
570
|
}
|
|
562
571
|
|
|
563
|
-
async stop({ did, updateStatus = true, silent = false }, context) {
|
|
564
|
-
logger.info('stop blocklet', { did });
|
|
572
|
+
async stop({ did, updateStatus = true, silent = false, componentDids }, context) {
|
|
573
|
+
logger.info('stop blocklet', { did, componentDids, updateStatus, silent });
|
|
565
574
|
|
|
566
575
|
const blocklet = await this.getBlocklet(did);
|
|
567
576
|
const { processId } = blocklet.env;
|
|
568
577
|
|
|
569
578
|
if (updateStatus) {
|
|
570
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping);
|
|
579
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping, { componentDids });
|
|
571
580
|
blocklet.status = BlockletStatus.stopping;
|
|
572
581
|
this.emit(BlockletEvents.statusChange, blocklet);
|
|
573
582
|
}
|
|
@@ -587,11 +596,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
587
596
|
silent,
|
|
588
597
|
...getHooksOutputFiles(b),
|
|
589
598
|
}),
|
|
599
|
+
componentDids,
|
|
590
600
|
});
|
|
591
601
|
} catch (error) {
|
|
592
602
|
logger.error('Failed to stop blocklet', { error, did });
|
|
593
603
|
if (updateStatus) {
|
|
594
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error);
|
|
604
|
+
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
595
605
|
this.emit(BlockletEvents.statusChange, res);
|
|
596
606
|
}
|
|
597
607
|
throw error;
|
|
@@ -600,13 +610,18 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
600
610
|
logger.info('blocklet stopped successfully', { processId, did });
|
|
601
611
|
|
|
602
612
|
if (updateStatus) {
|
|
603
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped);
|
|
613
|
+
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, { componentDids });
|
|
604
614
|
// send notification to websocket channel
|
|
605
615
|
this.emit(BlockletEvents.statusChange, res);
|
|
606
616
|
|
|
607
617
|
// send notification to wallet
|
|
608
618
|
this.emit(BlockletEvents.stopped, res);
|
|
609
619
|
|
|
620
|
+
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
621
|
+
appDid: blocklet.appDid,
|
|
622
|
+
components: getComponentsInternalInfo(res),
|
|
623
|
+
});
|
|
624
|
+
|
|
610
625
|
return res;
|
|
611
626
|
}
|
|
612
627
|
|
|
@@ -660,18 +675,25 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
660
675
|
* @param {Record<string, any>} context
|
|
661
676
|
* @returns {import('@abtnode/client').BlockletState}
|
|
662
677
|
*/
|
|
663
|
-
async restart({ did }, context) {
|
|
678
|
+
async restart({ did, componentDids }, context) {
|
|
664
679
|
logger.info('restart blocklet', { did });
|
|
665
680
|
|
|
666
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping);
|
|
681
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopping, { componentDids });
|
|
667
682
|
const result = await states.blocklet.getBlocklet(did);
|
|
668
683
|
this.emit(BlockletEvents.statusChange, result);
|
|
669
684
|
|
|
670
|
-
const ticket = this.startQueue.push({
|
|
685
|
+
const ticket = this.startQueue.push({
|
|
686
|
+
entity: 'blocklet',
|
|
687
|
+
action: 'restart',
|
|
688
|
+
id: did,
|
|
689
|
+
did,
|
|
690
|
+
componentDids,
|
|
691
|
+
context,
|
|
692
|
+
});
|
|
671
693
|
ticket.on('failed', async (err) => {
|
|
672
694
|
logger.error('failed to restart blocklet', { did, error: err });
|
|
673
695
|
|
|
674
|
-
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped);
|
|
696
|
+
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, { componentDids });
|
|
675
697
|
this.emit(BlockletEvents.statusChange, state);
|
|
676
698
|
|
|
677
699
|
this._createNotification(did, {
|
|
@@ -687,16 +709,28 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
687
709
|
}
|
|
688
710
|
|
|
689
711
|
// eslint-disable-next-line no-unused-vars
|
|
690
|
-
async reload({ did }, context) {
|
|
712
|
+
async reload({ did, componentDids: list }, context) {
|
|
691
713
|
const blocklet = await this.getBlocklet(did);
|
|
692
714
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
715
|
+
const componentDids = (blocklet.children || [])
|
|
716
|
+
.filter((x) => x.status === BlockletStatus.running)
|
|
717
|
+
.filter((x) => !shouldSkipComponent(x.meta.did, list))
|
|
718
|
+
.map((x) => x.meta.did);
|
|
697
719
|
|
|
698
|
-
|
|
699
|
-
|
|
720
|
+
if (!componentDids.length) {
|
|
721
|
+
throw new Error('No running component found');
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
try {
|
|
725
|
+
await reloadBlockletProcess(blocklet, { componentDids });
|
|
726
|
+
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.running, { componentDids });
|
|
727
|
+
logger.info('blocklet reload successfully', { did, componentDids });
|
|
728
|
+
this.emit(BlockletEvents.statusChange, res);
|
|
729
|
+
return res;
|
|
730
|
+
} catch (error) {
|
|
731
|
+
logger.error('Failed to reload blocklet', { error, did, componentDids });
|
|
732
|
+
throw error;
|
|
733
|
+
}
|
|
700
734
|
}
|
|
701
735
|
|
|
702
736
|
async delete({ did, keepData, keepLogsDir, keepConfigs }, context) {
|
|
@@ -755,17 +789,17 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
755
789
|
|
|
756
790
|
const blocklet = await this.getBlocklet(did);
|
|
757
791
|
|
|
758
|
-
if (
|
|
759
|
-
|
|
760
|
-
|
|
792
|
+
if (!childDid) {
|
|
793
|
+
if (isInProgress(blocklet.status || blocklet.status === BlockletStatus.running)) {
|
|
794
|
+
throw new Error('Cannot reset when blocklet is in progress');
|
|
795
|
+
}
|
|
761
796
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
797
|
+
try {
|
|
798
|
+
await this.deleteProcess({ did }, context);
|
|
799
|
+
} catch {
|
|
800
|
+
// do nothing
|
|
801
|
+
}
|
|
767
802
|
|
|
768
|
-
if (!childDid) {
|
|
769
803
|
// Cleanup disk storage
|
|
770
804
|
const { cacheDir, logsDir, dataDir } = blocklet.env;
|
|
771
805
|
fs.removeSync(cacheDir);
|
|
@@ -783,6 +817,16 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
783
817
|
throw new Error('Child does not exist');
|
|
784
818
|
}
|
|
785
819
|
|
|
820
|
+
if (isInProgress(child.status || child.status === BlockletStatus.running)) {
|
|
821
|
+
throw new Error('Cannot reset when component is in progress');
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
try {
|
|
825
|
+
await this.deleteProcess({ did, componentDids: [child.meta.did] }, context);
|
|
826
|
+
} catch {
|
|
827
|
+
// do nothing
|
|
828
|
+
}
|
|
829
|
+
|
|
786
830
|
// Cleanup disk storage
|
|
787
831
|
const { cacheDir, logsDir, dataDir } = child.env;
|
|
788
832
|
fs.removeSync(cacheDir);
|
|
@@ -864,6 +908,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
864
908
|
action: `/blocklets/${newBlocklet.meta.did}/components`,
|
|
865
909
|
});
|
|
866
910
|
|
|
911
|
+
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
912
|
+
appDid: blocklet.appDid,
|
|
913
|
+
components: getComponentsInternalInfo(newBlocklet),
|
|
914
|
+
});
|
|
915
|
+
|
|
867
916
|
return newBlocklet;
|
|
868
917
|
}
|
|
869
918
|
|
|
@@ -922,7 +971,14 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
922
971
|
// fallback blocklet status to error
|
|
923
972
|
const blocklet = await states.blocklet.getBlocklet(inputDid);
|
|
924
973
|
if (blocklet) {
|
|
925
|
-
|
|
974
|
+
const componentDids = [];
|
|
975
|
+
forEachComponentV2Sync(blocklet, (x) => {
|
|
976
|
+
if ([BlockletStatus.waiting, BlockletStatus.downloading].includes(x.status)) {
|
|
977
|
+
componentDids.push(x.meta.did);
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
await states.blocklet.setBlockletStatus(blocklet.meta.did, BlockletStatus.error, { componentDids });
|
|
926
982
|
}
|
|
927
983
|
statusLock.release();
|
|
928
984
|
} catch (err) {
|
|
@@ -935,15 +991,15 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
935
991
|
}
|
|
936
992
|
|
|
937
993
|
// eslint-disable-next-line no-unused-vars
|
|
938
|
-
async deleteProcess({ did }, context) {
|
|
994
|
+
async deleteProcess({ did, componentDids }, context) {
|
|
939
995
|
const blocklet = await this.getBlocklet(did);
|
|
940
996
|
|
|
941
|
-
logger.info('delete blocklet process', { did });
|
|
997
|
+
logger.info('delete blocklet process', { did, componentDids });
|
|
942
998
|
|
|
943
|
-
await deleteBlockletProcess(blocklet, context);
|
|
999
|
+
await deleteBlockletProcess(blocklet, { ...context, componentDids });
|
|
944
1000
|
|
|
945
|
-
const result = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped);
|
|
946
|
-
logger.info('blocklet process deleted successfully', { did });
|
|
1001
|
+
const result = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, { componentDids });
|
|
1002
|
+
logger.info('blocklet process deleted successfully', { did, componentDids });
|
|
947
1003
|
return result;
|
|
948
1004
|
}
|
|
949
1005
|
|
|
@@ -1021,19 +1077,18 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1021
1077
|
}
|
|
1022
1078
|
|
|
1023
1079
|
const tmpDids = Array.isArray(did) ? did : [did];
|
|
1024
|
-
const [rootDid,
|
|
1080
|
+
const [rootDid, childDid] = tmpDids;
|
|
1025
1081
|
const rootMetaDid = await states.blocklet.getBlockletMetaDid(rootDid);
|
|
1026
|
-
const dids = [rootMetaDid, ...childDids];
|
|
1027
1082
|
|
|
1028
|
-
logger.info('config blocklet', {
|
|
1083
|
+
logger.info('config blocklet', { rootDid, rootMetaDid, childDid });
|
|
1029
1084
|
|
|
1030
1085
|
const ancestors = [];
|
|
1031
1086
|
let blocklet = await this.getBlocklet(rootDid);
|
|
1032
|
-
|
|
1087
|
+
if (childDid) {
|
|
1033
1088
|
ancestors.push(blocklet);
|
|
1034
1089
|
blocklet = blocklet.children.find((x) => x.meta.did === childDid);
|
|
1035
1090
|
if (!blocklet) {
|
|
1036
|
-
throw new Error('Child blocklet does not exist', {
|
|
1091
|
+
throw new Error('Child blocklet does not exist', { rootDid, childDid });
|
|
1037
1092
|
}
|
|
1038
1093
|
}
|
|
1039
1094
|
|
|
@@ -1046,8 +1101,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1046
1101
|
await environmentNameSchema.validateAsync(x.key);
|
|
1047
1102
|
} else if (BLOCKLET_CONFIGURABLE_KEY[x.key] && x.key.startsWith('BLOCKLET_')) {
|
|
1048
1103
|
// app key
|
|
1049
|
-
if (
|
|
1050
|
-
logger.error(`Cannot set ${x.key} to child blocklet`,
|
|
1104
|
+
if (childDid) {
|
|
1105
|
+
logger.error(`Cannot set ${x.key} to child blocklet`, { rootDid, childDid });
|
|
1051
1106
|
throw new Error(`Cannot set ${x.key} to child blocklet`);
|
|
1052
1107
|
}
|
|
1053
1108
|
await validateAppConfig(x, states);
|
|
@@ -1086,7 +1141,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1086
1141
|
Object.assign(blocklet.configObj, configObj);
|
|
1087
1142
|
|
|
1088
1143
|
// update db
|
|
1089
|
-
await states.blockletExtras.setConfigs(
|
|
1144
|
+
await states.blockletExtras.setConfigs([rootMetaDid, childDid].filter(Boolean), newConfigs);
|
|
1090
1145
|
|
|
1091
1146
|
if (willAppSkChange) {
|
|
1092
1147
|
const info = await states.node.read();
|
|
@@ -1106,7 +1161,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1106
1161
|
}
|
|
1107
1162
|
|
|
1108
1163
|
// update blocklet meta
|
|
1109
|
-
if (blocklet.structVersion && !
|
|
1164
|
+
if (blocklet.structVersion && !childDid) {
|
|
1110
1165
|
const changedTitle = newConfigs.find((x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_NAME)?.value;
|
|
1111
1166
|
const changedDescription = newConfigs.find(
|
|
1112
1167
|
(x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_DESCRIPTION
|
|
@@ -1135,6 +1190,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1135
1190
|
await this._updateDidDocument(newState);
|
|
1136
1191
|
}
|
|
1137
1192
|
|
|
1193
|
+
if (!childDid && !newConfigs.some((x) => x.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SK)) {
|
|
1194
|
+
this.emit(BlockletInternalEvents.appConfigChanged, {
|
|
1195
|
+
appDid: newState.appDid,
|
|
1196
|
+
configs: newConfigs.map((x) => ({ key: x.key, value: x.value })),
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1138
1200
|
this.emit(BlockletEvents.updated, newState);
|
|
1139
1201
|
|
|
1140
1202
|
return newState;
|
|
@@ -1311,6 +1373,10 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1311
1373
|
await states.blocklet.updateBlocklet(rootDid, { mountPoint: blocklet.mountPoint, children: blocklet.children });
|
|
1312
1374
|
|
|
1313
1375
|
this.emit(BlockletEvents.upgraded, { blocklet, context: { ...context, createAuditLog: false } }); // trigger router refresh
|
|
1376
|
+
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
1377
|
+
appDid: blocklet.appDid,
|
|
1378
|
+
components: getComponentsInternalInfo(blocklet),
|
|
1379
|
+
});
|
|
1314
1380
|
|
|
1315
1381
|
return this.getBlocklet(rootDid);
|
|
1316
1382
|
}
|
|
@@ -1369,57 +1435,54 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1369
1435
|
return this.getBlocklet(did);
|
|
1370
1436
|
}
|
|
1371
1437
|
|
|
1372
|
-
async status(did, { forceSync = false } = {}) {
|
|
1373
|
-
const fastReturnOnForceSync = async (blocklet = {}) => {
|
|
1374
|
-
const { status } = blocklet;
|
|
1375
|
-
const { added, waiting, downloading, installing, installed, upgrading } = BlockletStatus;
|
|
1376
|
-
|
|
1377
|
-
if ([added, waiting, downloading, installing, installed, upgrading].includes(status)) {
|
|
1378
|
-
return blocklet;
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped);
|
|
1382
|
-
this.emit(BlockletEvents.statusChange, res);
|
|
1383
|
-
return res;
|
|
1384
|
-
};
|
|
1385
|
-
|
|
1438
|
+
async status(did, { forceSync = false, componentDids } = {}) {
|
|
1386
1439
|
const blocklet = await this.getBlocklet(did);
|
|
1387
1440
|
|
|
1388
|
-
|
|
1389
|
-
if (
|
|
1390
|
-
const uptime = Date.now() - new Date(blocklet.updatedAt).getTime();
|
|
1391
|
-
// FIXME @linchen 在彻底修复 blocklet status 稳定性之后, uptime check 应该去掉. 如果 hook 执行时间很长, uptime check 会影响 hook 执行过程中的 blocklet status
|
|
1392
|
-
if (uptime > 120 * 1000) {
|
|
1393
|
-
shouldUpdateStatus = true;
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
if (!shouldUpdateStatus) {
|
|
1441
|
+
// for backward compatibility
|
|
1442
|
+
if (!blocklet.structVersion) {
|
|
1398
1443
|
return blocklet;
|
|
1399
1444
|
}
|
|
1400
1445
|
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
!
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped);
|
|
1408
|
-
this.emit(BlockletEvents.statusChange, res);
|
|
1409
|
-
return res;
|
|
1410
|
-
}
|
|
1446
|
+
await forEachComponentV2(
|
|
1447
|
+
blocklet,
|
|
1448
|
+
async (component) => {
|
|
1449
|
+
if (!forceSync && !util.shouldUpdateBlockletStatus(component.status)) {
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1411
1452
|
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
this.emit(BlockletEvents.statusChange, res);
|
|
1416
|
-
return res;
|
|
1417
|
-
}
|
|
1453
|
+
if (shouldSkipComponent(component.meta.did, componentDids)) {
|
|
1454
|
+
return;
|
|
1455
|
+
}
|
|
1418
1456
|
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1457
|
+
try {
|
|
1458
|
+
const status = await getProcessState(component.env.processId);
|
|
1459
|
+
if (component.status !== status) {
|
|
1460
|
+
component.status = status;
|
|
1461
|
+
await states.blocklet.setBlockletStatus(did, status, { componentDids: [component.meta.did] });
|
|
1462
|
+
}
|
|
1463
|
+
} catch {
|
|
1464
|
+
if (
|
|
1465
|
+
![
|
|
1466
|
+
BlockletStatus.added,
|
|
1467
|
+
BlockletStatus.waiting,
|
|
1468
|
+
BlockletStatus.downloading,
|
|
1469
|
+
BlockletStatus.installing,
|
|
1470
|
+
BlockletStatus.installed,
|
|
1471
|
+
BlockletStatus.upgrading,
|
|
1472
|
+
].includes(component.status)
|
|
1473
|
+
) {
|
|
1474
|
+
const status = BlockletStatus.stopped;
|
|
1475
|
+
component.status = status;
|
|
1476
|
+
await states.blocklet.setBlockletStatus(did, status, { componentDids: [component.meta.did] });
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
},
|
|
1480
|
+
{ parallel: true }
|
|
1481
|
+
);
|
|
1482
|
+
|
|
1483
|
+
blocklet.status = getBlockletStatus(blocklet);
|
|
1484
|
+
|
|
1485
|
+
return blocklet;
|
|
1423
1486
|
}
|
|
1424
1487
|
|
|
1425
1488
|
async refreshListCache() {
|
|
@@ -1486,6 +1549,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1486
1549
|
name: 'sync-blocklet-status',
|
|
1487
1550
|
time: '*/60 * * * * *', // 60s
|
|
1488
1551
|
fn: this._syncBlockletStatus.bind(this),
|
|
1552
|
+
options: { runOnInit: false },
|
|
1489
1553
|
},
|
|
1490
1554
|
{
|
|
1491
1555
|
name: 'sync-blocklet-list',
|
|
@@ -1636,7 +1700,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1636
1700
|
* oldBlocklet: {},
|
|
1637
1701
|
* throwOnError: Error,
|
|
1638
1702
|
* skipCheckStatusBeforeDownload: boolean,
|
|
1639
|
-
*
|
|
1703
|
+
* componentDids: Array<did>,
|
|
1640
1704
|
* }} params
|
|
1641
1705
|
* @return {*}
|
|
1642
1706
|
* @memberof BlockletManager
|
|
@@ -1649,7 +1713,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1649
1713
|
oldBlocklet,
|
|
1650
1714
|
throwOnError,
|
|
1651
1715
|
skipCheckStatusBeforeDownload,
|
|
1652
|
-
|
|
1716
|
+
componentDids,
|
|
1653
1717
|
skipCheckIntegrity,
|
|
1654
1718
|
} = params;
|
|
1655
1719
|
const { meta } = blocklet;
|
|
@@ -1686,8 +1750,8 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1686
1750
|
const blockletForDownload = {
|
|
1687
1751
|
...blocklet,
|
|
1688
1752
|
children: (blocklet.children || []).filter((x) => {
|
|
1689
|
-
if (
|
|
1690
|
-
return
|
|
1753
|
+
if (componentDids?.length) {
|
|
1754
|
+
return componentDids.includes(x.meta.did);
|
|
1691
1755
|
}
|
|
1692
1756
|
return x;
|
|
1693
1757
|
}),
|
|
@@ -1758,12 +1822,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1758
1822
|
}
|
|
1759
1823
|
|
|
1760
1824
|
if (postAction === 'install') {
|
|
1761
|
-
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.installing);
|
|
1825
|
+
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.installing, { componentDids });
|
|
1762
1826
|
this.emit(BlockletEvents.statusChange, state);
|
|
1763
1827
|
}
|
|
1764
1828
|
|
|
1765
1829
|
if (postAction === 'upgrade') {
|
|
1766
|
-
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.upgrading);
|
|
1830
|
+
const state = await states.blocklet.setBlockletStatus(did, BlockletStatus.upgrading, { componentDids });
|
|
1767
1831
|
this.emit(BlockletEvents.statusChange, state);
|
|
1768
1832
|
}
|
|
1769
1833
|
|
|
@@ -1777,13 +1841,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1777
1841
|
try {
|
|
1778
1842
|
// install blocklet
|
|
1779
1843
|
if (postAction === 'install') {
|
|
1780
|
-
await this._onInstall({ blocklet, context, oldBlocklet });
|
|
1844
|
+
await this._onInstall({ blocklet, componentDids, context, oldBlocklet });
|
|
1781
1845
|
return;
|
|
1782
1846
|
}
|
|
1783
1847
|
|
|
1784
1848
|
// upgrade blocklet
|
|
1785
1849
|
if (postAction === 'upgrade') {
|
|
1786
|
-
await this._onUpgrade({ oldBlocklet, newBlocklet: blocklet, context });
|
|
1850
|
+
await this._onUpgrade({ oldBlocklet, componentDids, newBlocklet: blocklet, context });
|
|
1787
1851
|
}
|
|
1788
1852
|
} catch (error) {
|
|
1789
1853
|
if (throwOnError) {
|
|
@@ -1792,7 +1856,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1792
1856
|
}
|
|
1793
1857
|
}
|
|
1794
1858
|
|
|
1795
|
-
async _onInstall({ blocklet, context, oldBlocklet }) {
|
|
1859
|
+
async _onInstall({ blocklet, componentDids, context, oldBlocklet }) {
|
|
1796
1860
|
const { meta } = blocklet;
|
|
1797
1861
|
const { did, version } = meta;
|
|
1798
1862
|
logger.info('do install blocklet', { did, version });
|
|
@@ -1800,6 +1864,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1800
1864
|
try {
|
|
1801
1865
|
const installedBlocklet = await this._installBlocklet({
|
|
1802
1866
|
did,
|
|
1867
|
+
componentDids,
|
|
1803
1868
|
context,
|
|
1804
1869
|
oldBlocklet,
|
|
1805
1870
|
});
|
|
@@ -1807,7 +1872,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1807
1872
|
if (context.startImmediately && installedBlocklet?.settings.initialized) {
|
|
1808
1873
|
try {
|
|
1809
1874
|
logger.info('start blocklet after installed', { did });
|
|
1810
|
-
await this.start({ did, checkHealthImmediately: true });
|
|
1875
|
+
await this.start({ did, checkHealthImmediately: true, componentDids });
|
|
1811
1876
|
} catch (error) {
|
|
1812
1877
|
logger.warn('attempt to start immediately failed', { did, error });
|
|
1813
1878
|
}
|
|
@@ -1820,7 +1885,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1820
1885
|
}
|
|
1821
1886
|
}
|
|
1822
1887
|
|
|
1823
|
-
async _onUpgrade({ oldBlocklet, newBlocklet, context }) {
|
|
1888
|
+
async _onUpgrade({ oldBlocklet, newBlocklet, componentDids, context }) {
|
|
1824
1889
|
const { version, did } = newBlocklet.meta;
|
|
1825
1890
|
logger.info('do upgrade blocklet', { did, version });
|
|
1826
1891
|
|
|
@@ -1828,6 +1893,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1828
1893
|
await this._upgradeBlocklet({
|
|
1829
1894
|
newBlocklet,
|
|
1830
1895
|
oldBlocklet,
|
|
1896
|
+
componentDids,
|
|
1831
1897
|
context,
|
|
1832
1898
|
});
|
|
1833
1899
|
} catch (err) {
|
|
@@ -1835,13 +1901,13 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1835
1901
|
}
|
|
1836
1902
|
}
|
|
1837
1903
|
|
|
1838
|
-
async _onRestart({ did, context }) {
|
|
1839
|
-
await this.stop({ did, updateStatus: false }, context);
|
|
1840
|
-
await this.start({ did }, context);
|
|
1904
|
+
async _onRestart({ did, componentDids, context }) {
|
|
1905
|
+
await this.stop({ did, componentDids, updateStatus: false }, context);
|
|
1906
|
+
await this.start({ did, componentDids }, context);
|
|
1841
1907
|
}
|
|
1842
1908
|
|
|
1843
1909
|
async _onCheckIfStarted(jobInfo, { throwOnError } = {}) {
|
|
1844
|
-
const { did, context, minConsecutiveTime = 5000, timeout } = jobInfo;
|
|
1910
|
+
const { did, context, minConsecutiveTime = 5000, timeout, componentDids } = jobInfo;
|
|
1845
1911
|
const blocklet = await this.getBlocklet(did);
|
|
1846
1912
|
|
|
1847
1913
|
const { meta } = blocklet;
|
|
@@ -1849,10 +1915,18 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1849
1915
|
|
|
1850
1916
|
try {
|
|
1851
1917
|
// healthy check
|
|
1852
|
-
await checkBlockletProcessHealthy(blocklet, { minConsecutiveTime, timeout });
|
|
1918
|
+
await checkBlockletProcessHealthy(blocklet, { minConsecutiveTime, timeout, componentDids });
|
|
1853
1919
|
|
|
1854
1920
|
// update blocklet status after healthy check
|
|
1855
|
-
|
|
1921
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.running, { componentDids });
|
|
1922
|
+
|
|
1923
|
+
const res = await this.getBlocklet(did);
|
|
1924
|
+
|
|
1925
|
+
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
1926
|
+
appDid: blocklet.appDid,
|
|
1927
|
+
components: getComponentsInternalInfo(res),
|
|
1928
|
+
});
|
|
1929
|
+
|
|
1856
1930
|
this.emit(BlockletEvents.started, res);
|
|
1857
1931
|
} catch (error) {
|
|
1858
1932
|
const status = await states.blocklet.getBlockletStatus(did);
|
|
@@ -1864,7 +1938,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
1864
1938
|
logger.error('check blocklet if started failed', { did, name, context, timeout, error });
|
|
1865
1939
|
|
|
1866
1940
|
await this.deleteProcess({ did }, context);
|
|
1867
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.error);
|
|
1941
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids });
|
|
1868
1942
|
|
|
1869
1943
|
this._createNotification(did, {
|
|
1870
1944
|
title: 'Blocklet Start Failed',
|
|
@@ -2256,7 +2330,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2256
2330
|
* @param {string} opt.did
|
|
2257
2331
|
* @param {object} opt.context
|
|
2258
2332
|
*/
|
|
2259
|
-
async _installBlocklet({ did, oldBlocklet, context, createNotification = true }) {
|
|
2333
|
+
async _installBlocklet({ did, oldBlocklet, componentDids, context, createNotification = true }) {
|
|
2260
2334
|
try {
|
|
2261
2335
|
// should ensure blocklet integrity
|
|
2262
2336
|
let blocklet = await this.ensureBlocklet(did);
|
|
@@ -2280,7 +2354,9 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2280
2354
|
// post install
|
|
2281
2355
|
await this._runPostInstallHook(blocklet, context);
|
|
2282
2356
|
|
|
2283
|
-
await states.blocklet.
|
|
2357
|
+
await states.blocklet.setInstalledAt(did);
|
|
2358
|
+
|
|
2359
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.installed, { componentDids });
|
|
2284
2360
|
blocklet = await this.getBlocklet(did);
|
|
2285
2361
|
logger.info('blocklet installed', { source, did: meta.did });
|
|
2286
2362
|
|
|
@@ -2369,7 +2445,7 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2369
2445
|
}
|
|
2370
2446
|
}
|
|
2371
2447
|
|
|
2372
|
-
async _upgradeBlocklet({ newBlocklet, oldBlocklet, context = {} }) {
|
|
2448
|
+
async _upgradeBlocklet({ newBlocklet, oldBlocklet, componentDids, context = {} }) {
|
|
2373
2449
|
const { meta, source, deployedFrom, children } = newBlocklet;
|
|
2374
2450
|
const { did, version, name, title } = meta;
|
|
2375
2451
|
|
|
@@ -2434,11 +2510,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2434
2510
|
|
|
2435
2511
|
const status =
|
|
2436
2512
|
oldBlocklet.status === BlockletStatus.installed ? BlockletStatus.installed : BlockletStatus.stopped;
|
|
2437
|
-
await states.blocklet.setBlockletStatus(did, status, {
|
|
2513
|
+
await states.blocklet.setBlockletStatus(did, status, { componentDids });
|
|
2438
2514
|
|
|
2439
2515
|
// start new process
|
|
2440
2516
|
if (oldBlocklet.status === BlockletStatus.running) {
|
|
2441
|
-
await this.start({ did }, context);
|
|
2517
|
+
await this.start({ did, componentDids }, context);
|
|
2442
2518
|
logger.info('started blocklet for upgrading', { did, version });
|
|
2443
2519
|
}
|
|
2444
2520
|
|
|
@@ -2469,6 +2545,11 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2469
2545
|
|
|
2470
2546
|
await this._rollbackCache.remove({ did: blocklet.meta.did });
|
|
2471
2547
|
|
|
2548
|
+
this.emit(BlockletInternalEvents.componentsUpdated, {
|
|
2549
|
+
appDid: blocklet.appDid,
|
|
2550
|
+
components: getComponentsInternalInfo(blocklet),
|
|
2551
|
+
});
|
|
2552
|
+
|
|
2472
2553
|
return blocklet;
|
|
2473
2554
|
} catch (err) {
|
|
2474
2555
|
const b = await this._rollback('upgrade', did, oldBlocklet);
|
|
@@ -2525,10 +2606,12 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2525
2606
|
...context,
|
|
2526
2607
|
preDownload: async ({ downloadComponentIds }) => {
|
|
2527
2608
|
// update children status
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2609
|
+
if (downloadComponentIds?.length) {
|
|
2610
|
+
const blocklet1 = await states.blocklet.setBlockletStatus(did, BlockletStatus.downloading, {
|
|
2611
|
+
componentDids: downloadComponentIds,
|
|
2612
|
+
});
|
|
2613
|
+
this.emit(BlockletEvents.statusChange, blocklet1);
|
|
2614
|
+
}
|
|
2532
2615
|
},
|
|
2533
2616
|
onProgress: async (data) => {
|
|
2534
2617
|
this.emit(BlockletEvents.downloadBundleProgress, { appDid: appDid || did, meta: { did }, ...data });
|
|
@@ -2542,16 +2625,17 @@ class BlockletManager extends BaseBlockletManager {
|
|
|
2542
2625
|
});
|
|
2543
2626
|
}
|
|
2544
2627
|
|
|
2545
|
-
async _syncPm2Status(pm2Status, did) {
|
|
2628
|
+
async _syncPm2Status(pm2Status, did, componentDid) {
|
|
2546
2629
|
try {
|
|
2547
|
-
const
|
|
2548
|
-
|
|
2630
|
+
const blocklet = await states.blocklet.getBlocklet(did);
|
|
2631
|
+
const component = findComponentByIdV2(blocklet, componentDid);
|
|
2632
|
+
if (component && util.shouldUpdateBlockletStatus(component.status)) {
|
|
2549
2633
|
const newStatus = pm2StatusMap[pm2Status];
|
|
2550
|
-
await states.blocklet.setBlockletStatus(did, newStatus);
|
|
2551
|
-
logger.info('sync pm2 status to blocklet', { did, pm2Status, newStatus });
|
|
2634
|
+
await states.blocklet.setBlockletStatus(did, newStatus, { componentDids: [componentDid] });
|
|
2635
|
+
logger.info('sync pm2 status to blocklet', { did, componentDid, pm2Status, newStatus });
|
|
2552
2636
|
}
|
|
2553
2637
|
} catch (error) {
|
|
2554
|
-
logger.error('sync pm2 status to blocklet failed', { did, pm2Status, error });
|
|
2638
|
+
logger.error('sync pm2 status to blocklet failed', { did, componentDid, pm2Status, error });
|
|
2555
2639
|
}
|
|
2556
2640
|
}
|
|
2557
2641
|
|