@abtnode/core 1.17.3-beta-20251120-052956-035abea6 → 1.17.3-beta-20251123-232619-53258789
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 +176 -238
- package/lib/blocklet/manager/helper/blue-green-start-blocklet.js +234 -115
- package/lib/blocklet/manager/helper/blue-green-upgrade-blocklet.js +49 -3
- package/lib/event/index.js +1 -0
- package/lib/index.js +1 -0
- package/lib/states/blocklet.js +12 -10
- package/lib/states/notification.js +7 -5
- package/lib/team/manager.js +17 -3
- package/lib/util/blocklet.js +47 -4
- package/lib/util/docker/docker-exec-chown.js +3 -1
- package/lib/util/docker/docker-exec.js +4 -2
- package/lib/webhook/sender/slack/index.js +0 -1
- package/lib/webhook/sender/wallet/index.js +28 -10
- package/package.json +24 -24
|
@@ -259,13 +259,13 @@ const { formatEnvironments, getBlockletMeta, validateOwner, isCLI } = util;
|
|
|
259
259
|
|
|
260
260
|
const statusLock = new DBCache(() => ({
|
|
261
261
|
prefix: 'blocklet-status-lock',
|
|
262
|
-
ttl:
|
|
262
|
+
ttl: 120_000,
|
|
263
263
|
...getAbtNodeRedisAndSQLiteUrl(),
|
|
264
264
|
}));
|
|
265
265
|
|
|
266
266
|
const startLock = new DBCache(() => ({
|
|
267
267
|
prefix: 'blocklet-start-lock',
|
|
268
|
-
ttl: process.env.NODE_ENV === 'test' ?
|
|
268
|
+
ttl: process.env.NODE_ENV === 'test' ? 1_000 : 120_000,
|
|
269
269
|
...getAbtNodeRedisAndSQLiteUrl(),
|
|
270
270
|
}));
|
|
271
271
|
|
|
@@ -740,6 +740,8 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
740
740
|
e2eMode,
|
|
741
741
|
context,
|
|
742
742
|
atomic,
|
|
743
|
+
onStarted,
|
|
744
|
+
onError,
|
|
743
745
|
}) {
|
|
744
746
|
if (!blocklet.children) {
|
|
745
747
|
return componentDids;
|
|
@@ -771,11 +773,17 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
771
773
|
// start by dependency
|
|
772
774
|
for (const dids of requiredDidsLayers) {
|
|
773
775
|
if (atomic) {
|
|
774
|
-
await this._start(
|
|
776
|
+
await this._start(
|
|
777
|
+
{ blocklet, throwOnError, checkHealthImmediately, e2eMode, componentDids: dids, onStarted, onError },
|
|
778
|
+
context
|
|
779
|
+
);
|
|
775
780
|
} else {
|
|
776
781
|
const tasks = dids.map(
|
|
777
782
|
(x) => () =>
|
|
778
|
-
this._start(
|
|
783
|
+
this._start(
|
|
784
|
+
{ blocklet, throwOnError, checkHealthImmediately, e2eMode, componentDids: [x], onStarted, onError },
|
|
785
|
+
context
|
|
786
|
+
)
|
|
779
787
|
);
|
|
780
788
|
await pAll(tasks, { concurrency: 4 }).catch((err) => {
|
|
781
789
|
throw new Error(err.errors ? err.errors.join(', ') : err);
|
|
@@ -801,8 +809,8 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
801
809
|
},
|
|
802
810
|
context
|
|
803
811
|
) {
|
|
804
|
-
const lockName =
|
|
805
|
-
const shouldLock =
|
|
812
|
+
const lockName = `${did}-start`;
|
|
813
|
+
const shouldLock = inputComponentDids?.length === 0;
|
|
806
814
|
|
|
807
815
|
if (shouldLock) {
|
|
808
816
|
await startLock.acquire(lockName);
|
|
@@ -814,8 +822,16 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
814
822
|
inputComponentDids?.length ? inputComponentDids : blocklet.children.map((x) => x.meta.did)
|
|
815
823
|
);
|
|
816
824
|
|
|
825
|
+
try {
|
|
826
|
+
await this.deleteProcess({ did, componentDids: baseComponentDids, isGreen: true });
|
|
827
|
+
} catch (error) {
|
|
828
|
+
logger.warn('Failed to delete process; this warning can be safely ignored.', { error });
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
await this.checkControllerStatus(blocklet, 'start');
|
|
832
|
+
|
|
817
833
|
// 优先启动资源型组件
|
|
818
|
-
|
|
834
|
+
const componentDids = [];
|
|
819
835
|
const nonEntryComponentIds = [];
|
|
820
836
|
for (const b of blocklet.children) {
|
|
821
837
|
if (!b?.meta?.did) {
|
|
@@ -844,7 +860,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
844
860
|
operator,
|
|
845
861
|
});
|
|
846
862
|
}
|
|
847
|
-
|
|
848
863
|
// sync component config before at first to ensure resource component config is ready
|
|
849
864
|
const serverSk = (await states.node.read()).sk;
|
|
850
865
|
await Promise.all(
|
|
@@ -853,7 +868,16 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
853
868
|
)
|
|
854
869
|
);
|
|
855
870
|
|
|
856
|
-
|
|
871
|
+
const doc1 = await states.blocklet.setBlockletStatus(did, BlockletStatus.starting, {
|
|
872
|
+
componentDids,
|
|
873
|
+
operator,
|
|
874
|
+
});
|
|
875
|
+
|
|
876
|
+
this.emit(BlockletEvents.statusChange, doc1);
|
|
877
|
+
const startedBlockletDids = [];
|
|
878
|
+
const errorBlockletDids = [];
|
|
879
|
+
|
|
880
|
+
const notStartedComponentDids = await this.startRequiredComponents({
|
|
857
881
|
componentDids,
|
|
858
882
|
inputComponentDids,
|
|
859
883
|
blocklet,
|
|
@@ -862,26 +886,15 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
862
886
|
e2eMode,
|
|
863
887
|
context,
|
|
864
888
|
atomic,
|
|
889
|
+
onStarted: (subDid) => {
|
|
890
|
+
startedBlockletDids.push({ did: subDid });
|
|
891
|
+
},
|
|
892
|
+
onError: (subDid, error) => {
|
|
893
|
+
errorBlockletDids.push({ did: subDid, error });
|
|
894
|
+
},
|
|
865
895
|
});
|
|
866
896
|
|
|
867
|
-
|
|
868
|
-
const nextBlocklet = await this._start(
|
|
869
|
-
{ blocklet, throwOnError, checkHealthImmediately, e2eMode, componentDids, operator },
|
|
870
|
-
context
|
|
871
|
-
);
|
|
872
|
-
|
|
873
|
-
// 根据情况更新 route table, 会判断只有包含多 interfaces 的 DID 才会更新 route table
|
|
874
|
-
if (!['true', '1'].includes(process.env.ABT_NODE_DISABLE_BLUE_GREEN)) {
|
|
875
|
-
this.emit(BlockletEvents.blurOrGreenStarted, {
|
|
876
|
-
blocklet: nextBlocklet,
|
|
877
|
-
componentDids: inputComponentDids,
|
|
878
|
-
context,
|
|
879
|
-
});
|
|
880
|
-
}
|
|
881
|
-
return nextBlocklet;
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
const tasks = componentDids.map(
|
|
897
|
+
const tasks = notStartedComponentDids.map(
|
|
885
898
|
(componentDid) => () =>
|
|
886
899
|
this._start(
|
|
887
900
|
{
|
|
@@ -891,25 +904,104 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
891
904
|
e2eMode,
|
|
892
905
|
componentDids: [componentDid],
|
|
893
906
|
operator,
|
|
907
|
+
onStarted: (subDid) => {
|
|
908
|
+
startedBlockletDids.push({ did: subDid });
|
|
909
|
+
},
|
|
910
|
+
onError: (subDid, error) => {
|
|
911
|
+
errorBlockletDids.push({ did: subDid, error });
|
|
912
|
+
},
|
|
894
913
|
},
|
|
895
914
|
context
|
|
896
915
|
)
|
|
897
916
|
);
|
|
898
917
|
|
|
899
|
-
|
|
918
|
+
await pAll(tasks, { concurrency: 6 });
|
|
900
919
|
|
|
901
920
|
const nextBlocklet = await this.ensureBlocklet(did, { e2eMode });
|
|
921
|
+
let errorDescription = '';
|
|
922
|
+
let resultBlocklet = nextBlocklet;
|
|
923
|
+
|
|
924
|
+
if (startedBlockletDids.length) {
|
|
925
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.running, {
|
|
926
|
+
componentDids: startedBlockletDids.map((x) => x.did),
|
|
927
|
+
operator,
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
const finalBlocklet = await this.getBlocklet(did);
|
|
931
|
+
resultBlocklet = finalBlocklet;
|
|
932
|
+
|
|
933
|
+
await this.configSynchronizer.throttledSyncAppConfig(finalBlocklet);
|
|
934
|
+
const componentsInfo = getComponentsInternalInfo(finalBlocklet);
|
|
935
|
+
this.emit(BlockletInternalEvents.componentUpdated, {
|
|
936
|
+
appDid: blocklet.appDid,
|
|
937
|
+
components: componentsInfo,
|
|
938
|
+
});
|
|
939
|
+
this.emit(BlockletInternalEvents.componentStarted, {
|
|
940
|
+
appDid: blocklet.appDid,
|
|
941
|
+
components: (componentDids || []).map((x) => ({ did: x })),
|
|
942
|
+
});
|
|
943
|
+
|
|
944
|
+
this.emit(BlockletEvents.statusChange, finalBlocklet);
|
|
945
|
+
this.emit(BlockletEvents.started, { ...finalBlocklet, componentDids });
|
|
946
|
+
|
|
947
|
+
launcher.notifyBlockletStarted(finalBlocklet);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
if (errorBlockletDids.length) {
|
|
951
|
+
const error = errorBlockletDids[0];
|
|
952
|
+
for (const item of errorBlockletDids) {
|
|
953
|
+
logger.error('Failed to start blocklet', {
|
|
954
|
+
error: item.error,
|
|
955
|
+
title: nextBlocklet.meta.title,
|
|
956
|
+
name: getComponentNamesWithVersion(nextBlocklet, [item.did]),
|
|
957
|
+
});
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
errorDescription = `${getComponentNamesWithVersion(
|
|
961
|
+
nextBlocklet,
|
|
962
|
+
errorBlockletDids.map((x) => x.did)
|
|
963
|
+
)} start failed for ${getDisplayName(nextBlocklet)}: ${errorBlockletDids.map((x) => x.error.message).join('. ')}`;
|
|
964
|
+
this._createNotification(did, {
|
|
965
|
+
title: 'Component start failed',
|
|
966
|
+
description: errorDescription,
|
|
967
|
+
entityType: 'blocklet',
|
|
968
|
+
entityId: did,
|
|
969
|
+
severity: 'error',
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
await this.deleteProcess({
|
|
973
|
+
did,
|
|
974
|
+
componentDids: errorBlockletDids.map((x) => x.did),
|
|
975
|
+
shouldUpdateBlockletStatus: false,
|
|
976
|
+
});
|
|
977
|
+
await states.blocklet.setBlockletStatus(did, BlockletStatus.error, {
|
|
978
|
+
componentDids: errorBlockletDids.map((x) => x.did),
|
|
979
|
+
operator,
|
|
980
|
+
});
|
|
981
|
+
const finalBlocklet = await this.getBlocklet(did);
|
|
982
|
+
resultBlocklet = finalBlocklet;
|
|
983
|
+
this.emit(BlockletEvents.startFailed, {
|
|
984
|
+
...finalBlocklet,
|
|
985
|
+
componentDids: errorBlockletDids.map((x) => x.did),
|
|
986
|
+
error: { message: error.message },
|
|
987
|
+
});
|
|
988
|
+
this.emit(BlockletEvents.statusChange, { ...finalBlocklet, error: { message: error.message } });
|
|
989
|
+
}
|
|
902
990
|
|
|
903
991
|
// 根据情况更新 route table, 会判断只有包含多 interfaces 的 DID 才会更新 route table
|
|
904
992
|
if (!['true', '1'].includes(process.env.ABT_NODE_DISABLE_BLUE_GREEN)) {
|
|
905
993
|
this.emit(BlockletEvents.blurOrGreenStarted, {
|
|
906
|
-
blocklet:
|
|
994
|
+
blocklet: resultBlocklet,
|
|
907
995
|
componentDids: inputComponentDids,
|
|
908
996
|
context,
|
|
909
997
|
});
|
|
910
998
|
}
|
|
911
999
|
|
|
912
|
-
|
|
1000
|
+
if (throwOnError && errorDescription) {
|
|
1001
|
+
throw new Error(errorDescription);
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
return resultBlocklet;
|
|
913
1005
|
} finally {
|
|
914
1006
|
if (shouldLock) {
|
|
915
1007
|
await startLock.releaseLock(lockName);
|
|
@@ -926,17 +1018,13 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
926
1018
|
e2eMode = false,
|
|
927
1019
|
componentDids,
|
|
928
1020
|
operator: _operator,
|
|
1021
|
+
onStarted,
|
|
1022
|
+
onError,
|
|
929
1023
|
},
|
|
930
1024
|
context
|
|
931
1025
|
) {
|
|
932
1026
|
const operator = _operator || context?.user?.did;
|
|
933
1027
|
|
|
934
|
-
try {
|
|
935
|
-
await this.deleteProcess({ did, componentDids, isGreen: true });
|
|
936
|
-
} catch {
|
|
937
|
-
// do nothing
|
|
938
|
-
}
|
|
939
|
-
|
|
940
1028
|
logger.info('start blocklet', {
|
|
941
1029
|
did: did || inputBlocklet.meta.did,
|
|
942
1030
|
componentDids,
|
|
@@ -960,7 +1048,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
960
1048
|
|
|
961
1049
|
const entryComponentIds = [];
|
|
962
1050
|
const nonEntryComponentIds = [];
|
|
963
|
-
let nonEntryComponentRes;
|
|
964
1051
|
const componentDidsSet = new Set(componentDids);
|
|
965
1052
|
try {
|
|
966
1053
|
await forEachBlocklet(
|
|
@@ -996,18 +1083,9 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
996
1083
|
{ parallel: true, concurrencyLimit: 4 }
|
|
997
1084
|
);
|
|
998
1085
|
if (nonEntryComponentIds.length) {
|
|
999
|
-
const
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
minConsecutiveTime: 3000,
|
|
1003
|
-
timeout: 5000,
|
|
1004
|
-
componentDids: nonEntryComponentIds,
|
|
1005
|
-
};
|
|
1006
|
-
nonEntryComponentRes = await this._onCheckIfStarted(params, {
|
|
1007
|
-
throwOnError,
|
|
1008
|
-
skipRunningCheck: true,
|
|
1009
|
-
needUpdateBlueStatus: false,
|
|
1010
|
-
});
|
|
1086
|
+
for (const subDid of nonEntryComponentIds) {
|
|
1087
|
+
onStarted?.(subDid);
|
|
1088
|
+
}
|
|
1011
1089
|
}
|
|
1012
1090
|
} catch (err) {
|
|
1013
1091
|
logger.error('Failed to categorize components into entry and non-entry types', { error: err.message });
|
|
@@ -1015,7 +1093,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1015
1093
|
}
|
|
1016
1094
|
|
|
1017
1095
|
if (!entryComponentIds.length) {
|
|
1018
|
-
return
|
|
1096
|
+
return;
|
|
1019
1097
|
}
|
|
1020
1098
|
|
|
1021
1099
|
try {
|
|
@@ -1036,13 +1114,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1036
1114
|
}
|
|
1037
1115
|
}
|
|
1038
1116
|
|
|
1039
|
-
const doc1 = await states.blocklet.setBlockletStatus(did, BlockletStatus.starting, {
|
|
1040
|
-
componentDids: entryComponentIds,
|
|
1041
|
-
operator,
|
|
1042
|
-
});
|
|
1043
|
-
|
|
1044
1117
|
blocklet1.status = BlockletStatus.starting;
|
|
1045
|
-
this.emit(BlockletEvents.statusChange, doc1);
|
|
1046
1118
|
const blocklet = await ensureAppPortsNotOccupied({
|
|
1047
1119
|
blocklet: blocklet1,
|
|
1048
1120
|
componentDids: entryComponentIds,
|
|
@@ -1097,8 +1169,6 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1097
1169
|
});
|
|
1098
1170
|
};
|
|
1099
1171
|
|
|
1100
|
-
await this.configSynchronizer.syncAppConfig(blocklet);
|
|
1101
|
-
|
|
1102
1172
|
await startBlockletProcess(blocklet, {
|
|
1103
1173
|
...context,
|
|
1104
1174
|
preFlight: getHookFn('preFlight'),
|
|
@@ -1116,6 +1186,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1116
1186
|
checkHealthImmediately,
|
|
1117
1187
|
componentDids,
|
|
1118
1188
|
});
|
|
1189
|
+
|
|
1119
1190
|
const params = {
|
|
1120
1191
|
did,
|
|
1121
1192
|
context,
|
|
@@ -1124,47 +1195,19 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1124
1195
|
componentDids: entryComponentIds,
|
|
1125
1196
|
};
|
|
1126
1197
|
|
|
1127
|
-
await this._onCheckIfStarted(params, { throwOnError
|
|
1128
|
-
blocklet.status = BlockletStatus.running;
|
|
1198
|
+
await this._onCheckIfStarted(params, { throwOnError });
|
|
1129
1199
|
|
|
1130
|
-
|
|
1200
|
+
for (const subDid of entryComponentIds) {
|
|
1201
|
+
onStarted?.(subDid);
|
|
1202
|
+
}
|
|
1131
1203
|
} catch (err) {
|
|
1132
1204
|
const status = await states.blocklet.getBlockletStatus(did);
|
|
1133
1205
|
if ([BlockletStatus.stopping, BlockletStatus.stopped].includes(status)) {
|
|
1134
1206
|
logger.info('Failed to start blocklet maybe due to manually stopped');
|
|
1135
|
-
return states.blocklet.getBlocklet(did);
|
|
1136
1207
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
logger.error('Failed to start blocklet', { error, did, title: blocklet1.meta.title });
|
|
1140
|
-
const description = `${getComponentNamesWithVersion(blocklet1, entryComponentIds)} start failed for ${getDisplayName(
|
|
1141
|
-
blocklet1
|
|
1142
|
-
)}: ${error.message}`;
|
|
1143
|
-
this._createNotification(did, {
|
|
1144
|
-
title: 'Component start failed',
|
|
1145
|
-
description,
|
|
1146
|
-
entityType: 'blocklet',
|
|
1147
|
-
entityId: did,
|
|
1148
|
-
severity: 'error',
|
|
1149
|
-
});
|
|
1150
|
-
|
|
1151
|
-
await this.deleteProcess({ did, componentDids: entryComponentIds });
|
|
1152
|
-
const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error, {
|
|
1153
|
-
componentDids: entryComponentIds,
|
|
1154
|
-
operator,
|
|
1155
|
-
});
|
|
1156
|
-
this.emit(BlockletEvents.startFailed, {
|
|
1157
|
-
...res,
|
|
1158
|
-
componentDids: entryComponentIds,
|
|
1159
|
-
error: { message: error.message },
|
|
1160
|
-
});
|
|
1161
|
-
this.emit(BlockletEvents.statusChange, { ...res, error: { message: error.message } });
|
|
1162
|
-
|
|
1163
|
-
if (throwOnError) {
|
|
1164
|
-
throw new Error(description);
|
|
1208
|
+
for (const subDid of entryComponentIds) {
|
|
1209
|
+
onError?.(subDid, err);
|
|
1165
1210
|
}
|
|
1166
|
-
|
|
1167
|
-
return res;
|
|
1168
1211
|
}
|
|
1169
1212
|
}
|
|
1170
1213
|
|
|
@@ -1471,13 +1514,19 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1471
1514
|
});
|
|
1472
1515
|
|
|
1473
1516
|
const doc = await this._deleteBlocklet({ did, keepData, keepLogsDir, keepConfigs }, context);
|
|
1474
|
-
this._createNotification(
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1517
|
+
this._createNotification(
|
|
1518
|
+
doc.meta.did,
|
|
1519
|
+
{
|
|
1520
|
+
title: 'Blocklet Deleted',
|
|
1521
|
+
description: `Blocklet ${getDisplayName(blocklet)} is deleted.`,
|
|
1522
|
+
entityType: 'blocklet',
|
|
1523
|
+
entityId: doc.meta.did,
|
|
1524
|
+
severity: 'success',
|
|
1525
|
+
},
|
|
1526
|
+
{
|
|
1527
|
+
skipGetBlocklet: true,
|
|
1528
|
+
}
|
|
1529
|
+
);
|
|
1481
1530
|
await removeDockerNetwork(parseDockerName(did, 'docker-network'));
|
|
1482
1531
|
return doc;
|
|
1483
1532
|
} catch (error) {
|
|
@@ -1486,13 +1535,19 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
1486
1535
|
const doc = await this._deleteBlocklet({ did, keepData, keepLogsDir, keepConfigs }, context);
|
|
1487
1536
|
await removeDockerNetwork(parseDockerName(did, 'docker-network'));
|
|
1488
1537
|
|
|
1489
|
-
this._createNotification(
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1538
|
+
this._createNotification(
|
|
1539
|
+
doc.meta.did,
|
|
1540
|
+
{
|
|
1541
|
+
title: 'Blocklet Deleted',
|
|
1542
|
+
description: `Blocklet ${getDisplayName(blocklet)} is deleted.`,
|
|
1543
|
+
entityType: 'blocklet',
|
|
1544
|
+
entityId: doc.meta.did,
|
|
1545
|
+
severity: 'success',
|
|
1546
|
+
},
|
|
1547
|
+
{
|
|
1548
|
+
skipGetBlocklet: true,
|
|
1549
|
+
}
|
|
1550
|
+
);
|
|
1496
1551
|
|
|
1497
1552
|
return doc;
|
|
1498
1553
|
}
|
|
@@ -3590,141 +3645,24 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
3590
3645
|
await blueGreenStartBlocklet({ did, componentDids, operator }, context, this, states);
|
|
3591
3646
|
}
|
|
3592
3647
|
|
|
3593
|
-
_onCheckIfStarted = async (
|
|
3594
|
-
jobInfo
|
|
3595
|
-
{ throwOnError, skipRunningCheck = false, isGreen = false, needUpdateBlueStatus = true } = {}
|
|
3596
|
-
) => {
|
|
3597
|
-
const startedAt = Date.now();
|
|
3598
|
-
const { did, context, minConsecutiveTime = 2000, timeout, componentDids } = jobInfo;
|
|
3599
|
-
const nodeInfo = await states.node.read();
|
|
3648
|
+
_onCheckIfStarted = async (jobInfo, { skipRunningCheck = false, isGreen = false } = {}) => {
|
|
3649
|
+
const { did, minConsecutiveTime = 2000, timeout, componentDids } = jobInfo;
|
|
3600
3650
|
const blocklet = await this.getBlocklet(did);
|
|
3601
3651
|
|
|
3602
|
-
const
|
|
3603
|
-
const { name } = meta;
|
|
3604
|
-
|
|
3605
|
-
const successBlockletIds = new Set();
|
|
3606
|
-
|
|
3607
|
-
try {
|
|
3608
|
-
if (!skipRunningCheck) {
|
|
3609
|
-
await checkBlockletProcessHealthy(blocklet, {
|
|
3610
|
-
minConsecutiveTime,
|
|
3611
|
-
timeout,
|
|
3612
|
-
componentDids,
|
|
3613
|
-
isGreen,
|
|
3614
|
-
appDid: did,
|
|
3615
|
-
enableDocker: nodeInfo.enableDocker,
|
|
3616
|
-
getBlocklet: () => {
|
|
3617
|
-
return this.getBlocklet(did);
|
|
3618
|
-
},
|
|
3619
|
-
setBlockletRunning: async (componentDid) => {
|
|
3620
|
-
successBlockletIds.add(componentDid);
|
|
3621
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.running, {
|
|
3622
|
-
componentDids: [componentDid],
|
|
3623
|
-
isGreen,
|
|
3624
|
-
});
|
|
3625
|
-
},
|
|
3626
|
-
});
|
|
3627
|
-
}
|
|
3652
|
+
const nodeInfo = await states.node.read();
|
|
3628
3653
|
|
|
3629
|
-
|
|
3630
|
-
|
|
3654
|
+
if (!skipRunningCheck) {
|
|
3655
|
+
await checkBlockletProcessHealthy(blocklet, {
|
|
3656
|
+
minConsecutiveTime,
|
|
3657
|
+
timeout,
|
|
3658
|
+
componentDids,
|
|
3631
3659
|
isGreen,
|
|
3660
|
+
appDid: did,
|
|
3661
|
+
enableDocker: nodeInfo.enableDocker,
|
|
3662
|
+
getBlocklet: () => {
|
|
3663
|
+
return this.getBlocklet(did);
|
|
3664
|
+
},
|
|
3632
3665
|
});
|
|
3633
|
-
|
|
3634
|
-
if (needUpdateBlueStatus) {
|
|
3635
|
-
await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, {
|
|
3636
|
-
componentDids,
|
|
3637
|
-
isGreen: !isGreen,
|
|
3638
|
-
});
|
|
3639
|
-
}
|
|
3640
|
-
|
|
3641
|
-
const nextBlocklet = await this.getBlocklet(did);
|
|
3642
|
-
|
|
3643
|
-
await this.configSynchronizer.throttledSyncAppConfig(nextBlocklet);
|
|
3644
|
-
const componentsInfo = getComponentsInternalInfo(nextBlocklet);
|
|
3645
|
-
this.emit(BlockletInternalEvents.componentUpdated, {
|
|
3646
|
-
appDid: blocklet.appDid,
|
|
3647
|
-
components: componentsInfo,
|
|
3648
|
-
});
|
|
3649
|
-
this.emit(BlockletInternalEvents.componentStarted, {
|
|
3650
|
-
appDid: blocklet.appDid,
|
|
3651
|
-
components: (componentDids || []).map((x) => ({ did: x })),
|
|
3652
|
-
});
|
|
3653
|
-
|
|
3654
|
-
this.emit(BlockletEvents.statusChange, nextBlocklet);
|
|
3655
|
-
this.emit(BlockletEvents.started, { ...nextBlocklet, componentDids });
|
|
3656
|
-
|
|
3657
|
-
launcher.notifyBlockletStarted(blocklet);
|
|
3658
|
-
|
|
3659
|
-
logger.info('blocklet healthy', { did, name, time: Date.now() - startedAt });
|
|
3660
|
-
|
|
3661
|
-
if (needUpdateBlueStatus) {
|
|
3662
|
-
try {
|
|
3663
|
-
await this.deleteProcess({ did, componentDids, isGreen: !isGreen }, context);
|
|
3664
|
-
} catch {
|
|
3665
|
-
logger.error('delete process failed', { did, componentDids, isGreen });
|
|
3666
|
-
}
|
|
3667
|
-
}
|
|
3668
|
-
|
|
3669
|
-
return runningRes;
|
|
3670
|
-
} catch (error) {
|
|
3671
|
-
const errorBlockletIds = [];
|
|
3672
|
-
for (const componentDid of componentDids) {
|
|
3673
|
-
if (!successBlockletIds.has(componentDid)) {
|
|
3674
|
-
errorBlockletIds.push(componentDid);
|
|
3675
|
-
}
|
|
3676
|
-
}
|
|
3677
|
-
if (errorBlockletIds.length === 0) {
|
|
3678
|
-
return this.getBlocklet(did);
|
|
3679
|
-
}
|
|
3680
|
-
|
|
3681
|
-
const status = await states.blocklet.getBlockletStatus(did);
|
|
3682
|
-
if ([BlockletStatus.stopping, BlockletStatus.stopped].includes(status)) {
|
|
3683
|
-
logger.info(`Check blocklet healthy failing because blocklet is ${fromBlockletStatus(status)}`);
|
|
3684
|
-
return {};
|
|
3685
|
-
}
|
|
3686
|
-
|
|
3687
|
-
logger.error('check blocklet if started failed', { did, name, context, timeout, error });
|
|
3688
|
-
|
|
3689
|
-
await this.deleteProcess({ did, componentDids: errorBlockletIds, isGreen }, context);
|
|
3690
|
-
|
|
3691
|
-
let doc;
|
|
3692
|
-
if (isGreen) {
|
|
3693
|
-
doc = await states.blocklet.setBlockletStatus(did, BlockletStatus.stopped, {
|
|
3694
|
-
componentDids: errorBlockletIds,
|
|
3695
|
-
isGreen,
|
|
3696
|
-
});
|
|
3697
|
-
} else {
|
|
3698
|
-
doc = await states.blocklet.setBlockletStatus(did, BlockletStatus.error, { componentDids: errorBlockletIds });
|
|
3699
|
-
}
|
|
3700
|
-
|
|
3701
|
-
const componentNames = getComponentNamesWithVersion(blocklet, errorBlockletIds);
|
|
3702
|
-
const description = componentNames
|
|
3703
|
-
? `${getComponentNamesWithVersion(blocklet, errorBlockletIds)} start failed for ${getDisplayName(blocklet)}: ${
|
|
3704
|
-
error.message
|
|
3705
|
-
}`
|
|
3706
|
-
: `${blocklet.meta.title} start failed: ${error.message}`;
|
|
3707
|
-
|
|
3708
|
-
this._createNotification(did, {
|
|
3709
|
-
title: 'Component start failed',
|
|
3710
|
-
description,
|
|
3711
|
-
entityType: 'blocklet',
|
|
3712
|
-
entityId: did,
|
|
3713
|
-
severity: 'error',
|
|
3714
|
-
});
|
|
3715
|
-
|
|
3716
|
-
this.emit(BlockletEvents.startFailed, {
|
|
3717
|
-
...doc,
|
|
3718
|
-
componentDids: errorBlockletIds,
|
|
3719
|
-
error: { message: error.message },
|
|
3720
|
-
});
|
|
3721
|
-
this.emit(BlockletEvents.statusChange, { ...doc, error });
|
|
3722
|
-
|
|
3723
|
-
if (throwOnError) {
|
|
3724
|
-
throw error;
|
|
3725
|
-
}
|
|
3726
|
-
|
|
3727
|
-
return doc;
|
|
3728
3666
|
}
|
|
3729
3667
|
};
|
|
3730
3668
|
|
|
@@ -5185,7 +5123,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
5185
5123
|
}
|
|
5186
5124
|
|
|
5187
5125
|
// 目前:Blocklet 的安装消息都会聚合在这里。
|
|
5188
|
-
async _createNotification(did, notification) {
|
|
5126
|
+
async _createNotification(did, notification, { skipGetBlocklet = false } = {}) {
|
|
5189
5127
|
if (isCLI()) {
|
|
5190
5128
|
return undefined;
|
|
5191
5129
|
}
|
|
@@ -5194,7 +5132,7 @@ class DiskBlockletManager extends BaseBlockletManager {
|
|
|
5194
5132
|
let blockletUrl;
|
|
5195
5133
|
let blocklet;
|
|
5196
5134
|
try {
|
|
5197
|
-
blocklet = await this.getBlocklet(did);
|
|
5135
|
+
blocklet = skipGetBlocklet ? null : await this.getBlocklet(did);
|
|
5198
5136
|
if (blocklet) {
|
|
5199
5137
|
const urls = blocklet.site?.domainAliases || [];
|
|
5200
5138
|
const customUrl = urls.find((x) => !x.isProtected)?.value;
|