@cadenza.io/service 2.17.4 → 2.17.6
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/dist/browser/index.js +235 -37
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +235 -37
- package/dist/browser/index.mjs.map +1 -1
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +235 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +235 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -480,6 +480,9 @@ function normalizeServiceInstanceDescriptor(value) {
|
|
|
480
480
|
health: raw.health ?? {},
|
|
481
481
|
isFrontend: Boolean(raw.isFrontend ?? raw.is_frontend ?? false),
|
|
482
482
|
isDatabase: Boolean(raw.isDatabase ?? raw.is_database ?? false),
|
|
483
|
+
isBootstrapPlaceholder: Boolean(
|
|
484
|
+
raw.isBootstrapPlaceholder ?? raw.is_bootstrap_placeholder ?? false
|
|
485
|
+
),
|
|
483
486
|
transports,
|
|
484
487
|
clientCreatedTransportIds: Array.isArray(raw.clientCreatedTransportIds) ? raw.clientCreatedTransportIds.map((entry) => normalizeString2(entry)).filter((entry) => entry.length > 0) : void 0
|
|
485
488
|
};
|
|
@@ -893,6 +896,7 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
893
896
|
health: ctx.health ?? ctx.__health ?? {},
|
|
894
897
|
numberOfRunningGraphs: ctx.numberOfRunningGraphs ?? ctx.__numberOfRunningGraphs ?? 0,
|
|
895
898
|
isPrimary: false,
|
|
899
|
+
isBootstrapPlaceholder: !!ctx.isBootstrapPlaceholder,
|
|
896
900
|
transports: ctx.transports ?? []
|
|
897
901
|
} : void 0)
|
|
898
902
|
);
|
|
@@ -947,6 +951,9 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
947
951
|
trackedInstance.acceptingWork = snapshot.acceptingWork;
|
|
948
952
|
trackedInstance.reportedAt = trackedInstance.reportedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
949
953
|
}
|
|
954
|
+
if (!serviceInstance.isBootstrapPlaceholder) {
|
|
955
|
+
this.reconcileBootstrapPlaceholderInstance(serviceName, uuid5, emit);
|
|
956
|
+
}
|
|
950
957
|
if (this.serviceName === serviceName) {
|
|
951
958
|
return false;
|
|
952
959
|
}
|
|
@@ -1793,12 +1800,14 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
1793
1800
|
this.useSocket ? "socket" : "rest"
|
|
1794
1801
|
) : void 0;
|
|
1795
1802
|
const message = error instanceof Error ? error.message : String(error);
|
|
1803
|
+
const diagnostics = error && typeof error === "object" && "runtimeStatusFallback" in error && error.runtimeStatusFallback && typeof error.runtimeStatusFallback === "object" ? error.runtimeStatusFallback : void 0;
|
|
1796
1804
|
CadenzaService.log(
|
|
1797
1805
|
"Runtime status fallback inquiry failed.",
|
|
1798
1806
|
{
|
|
1799
1807
|
serviceName,
|
|
1800
1808
|
serviceInstanceId,
|
|
1801
|
-
error: message
|
|
1809
|
+
error: message,
|
|
1810
|
+
diagnostics
|
|
1802
1811
|
},
|
|
1803
1812
|
"warning"
|
|
1804
1813
|
);
|
|
@@ -2288,6 +2297,67 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2288
2297
|
}
|
|
2289
2298
|
return this.getInstance(this.serviceName, this.serviceInstanceId);
|
|
2290
2299
|
}
|
|
2300
|
+
summarizeTransportForDebug(transport) {
|
|
2301
|
+
if (!transport) {
|
|
2302
|
+
return void 0;
|
|
2303
|
+
}
|
|
2304
|
+
return {
|
|
2305
|
+
uuid: transport.uuid,
|
|
2306
|
+
role: transport.role,
|
|
2307
|
+
origin: transport.origin,
|
|
2308
|
+
protocols: transport.protocols,
|
|
2309
|
+
clientCreated: transport.clientCreated
|
|
2310
|
+
};
|
|
2311
|
+
}
|
|
2312
|
+
summarizeInstanceForRuntimeStatusFallback(instance) {
|
|
2313
|
+
return {
|
|
2314
|
+
exists: Boolean(instance),
|
|
2315
|
+
runtimeState: instance?.runtimeState,
|
|
2316
|
+
acceptingWork: instance?.acceptingWork,
|
|
2317
|
+
reportedAt: instance?.reportedAt ?? null,
|
|
2318
|
+
isDatabase: instance?.isDatabase,
|
|
2319
|
+
isFrontend: instance?.isFrontend,
|
|
2320
|
+
isBootstrapPlaceholder: instance?.isBootstrapPlaceholder,
|
|
2321
|
+
transports: (instance?.transports ?? []).map((transport) => ({
|
|
2322
|
+
uuid: transport.uuid,
|
|
2323
|
+
role: transport.role,
|
|
2324
|
+
origin: transport.origin,
|
|
2325
|
+
protocols: transport.protocols,
|
|
2326
|
+
clientCreated: transport.clientCreated
|
|
2327
|
+
}))
|
|
2328
|
+
};
|
|
2329
|
+
}
|
|
2330
|
+
summarizeRuntimeStatusInquiryReports(inquiryResult) {
|
|
2331
|
+
const reports = Array.isArray(inquiryResult.runtimeStatusReports) ? inquiryResult.runtimeStatusReports : [];
|
|
2332
|
+
return reports.map((candidate) => {
|
|
2333
|
+
const normalized = this.normalizeRuntimeStatusReport(candidate);
|
|
2334
|
+
if (normalized) {
|
|
2335
|
+
return {
|
|
2336
|
+
serviceName: normalized.serviceName,
|
|
2337
|
+
serviceInstanceId: normalized.serviceInstanceId,
|
|
2338
|
+
transportId: normalized.transportId,
|
|
2339
|
+
state: normalized.state,
|
|
2340
|
+
acceptingWork: normalized.acceptingWork,
|
|
2341
|
+
reportedAt: normalized.reportedAt
|
|
2342
|
+
};
|
|
2343
|
+
}
|
|
2344
|
+
const raw = candidate && typeof candidate === "object" ? candidate : {};
|
|
2345
|
+
const rawState = raw.state === "healthy" || raw.state === "degraded" || raw.state === "overloaded" || raw.state === "unavailable" ? raw.state : void 0;
|
|
2346
|
+
return {
|
|
2347
|
+
serviceName: typeof raw.serviceName === "string" ? raw.serviceName : typeof raw.__serviceName === "string" ? raw.__serviceName : void 0,
|
|
2348
|
+
serviceInstanceId: typeof raw.serviceInstanceId === "string" ? raw.serviceInstanceId : typeof raw.__serviceInstanceId === "string" ? raw.__serviceInstanceId : void 0,
|
|
2349
|
+
transportId: typeof raw.transportId === "string" ? raw.transportId : typeof raw.serviceTransportId === "string" ? raw.serviceTransportId : void 0,
|
|
2350
|
+
state: rawState,
|
|
2351
|
+
acceptingWork: typeof raw.acceptingWork === "boolean" ? raw.acceptingWork : void 0,
|
|
2352
|
+
reportedAt: typeof raw.reportedAt === "string" ? raw.reportedAt : void 0
|
|
2353
|
+
};
|
|
2354
|
+
});
|
|
2355
|
+
}
|
|
2356
|
+
createRuntimeStatusFallbackError(message, diagnostics) {
|
|
2357
|
+
return Object.assign(new Error(message), {
|
|
2358
|
+
runtimeStatusFallback: diagnostics
|
|
2359
|
+
});
|
|
2360
|
+
}
|
|
2291
2361
|
resolveLocalStatusCheck(ctx = {}) {
|
|
2292
2362
|
if (!this.serviceName) {
|
|
2293
2363
|
return {
|
|
@@ -2414,6 +2484,39 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2414
2484
|
this.missedHeartbeatsByInstance.delete(serviceInstanceId);
|
|
2415
2485
|
this.runtimeStatusFallbackInFlightByInstance.delete(serviceInstanceId);
|
|
2416
2486
|
}
|
|
2487
|
+
reconcileBootstrapPlaceholderInstance(serviceName, resolvedInstanceId, emit) {
|
|
2488
|
+
const instances = this.instances.get(serviceName);
|
|
2489
|
+
if (!instances?.length) {
|
|
2490
|
+
return;
|
|
2491
|
+
}
|
|
2492
|
+
const placeholders = instances.filter(
|
|
2493
|
+
(instance) => instance.uuid !== resolvedInstanceId && instance.isBootstrapPlaceholder
|
|
2494
|
+
);
|
|
2495
|
+
if (!placeholders.length) {
|
|
2496
|
+
return;
|
|
2497
|
+
}
|
|
2498
|
+
for (const placeholder of placeholders) {
|
|
2499
|
+
const wasDependee = this.dependeeByInstance.has(placeholder.uuid);
|
|
2500
|
+
const requiredForReadiness = this.readinessDependeeByInstance.has(
|
|
2501
|
+
placeholder.uuid
|
|
2502
|
+
);
|
|
2503
|
+
for (const transport of placeholder.transports) {
|
|
2504
|
+
const transportKey = buildTransportClientKey(transport);
|
|
2505
|
+
emit(`meta.socket_shutdown_requested:${transportKey}`, {});
|
|
2506
|
+
emit(`meta.fetch.destroy_requested:${transportKey}`, {});
|
|
2507
|
+
}
|
|
2508
|
+
this.unregisterDependee(placeholder.uuid, serviceName);
|
|
2509
|
+
if (wasDependee) {
|
|
2510
|
+
this.registerDependee(serviceName, resolvedInstanceId, {
|
|
2511
|
+
requiredForReadiness
|
|
2512
|
+
});
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
this.instances.set(
|
|
2516
|
+
serviceName,
|
|
2517
|
+
instances.filter((instance) => !instance.isBootstrapPlaceholder)
|
|
2518
|
+
);
|
|
2519
|
+
}
|
|
2417
2520
|
getHeartbeatMisses(serviceInstanceId, now = Date.now()) {
|
|
2418
2521
|
const observedMisses = this.missedHeartbeatsByInstance.get(serviceInstanceId) ?? 0;
|
|
2419
2522
|
const lastHeartbeatAt = this.lastHeartbeatAtByInstance.get(serviceInstanceId) ?? 0;
|
|
@@ -2607,32 +2710,48 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2607
2710
|
}
|
|
2608
2711
|
async resolveRuntimeStatusFallbackInquiry(serviceName, serviceInstanceId, options = {}) {
|
|
2609
2712
|
const instance = this.getInstance(serviceName, serviceInstanceId);
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
this.
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2713
|
+
const directStatusCheck = instance ? await this.requestRuntimeStatusViaRest(
|
|
2714
|
+
instance,
|
|
2715
|
+
serviceName,
|
|
2716
|
+
serviceInstanceId
|
|
2717
|
+
) : {
|
|
2718
|
+
report: null,
|
|
2719
|
+
diagnostic: {
|
|
2720
|
+
attempted: false,
|
|
2721
|
+
outcome: "instance_missing"
|
|
2722
|
+
}
|
|
2723
|
+
};
|
|
2724
|
+
if (directStatusCheck.report) {
|
|
2725
|
+
if (!this.applyRuntimeStatusReport(directStatusCheck.report)) {
|
|
2726
|
+
throw this.createRuntimeStatusFallbackError(
|
|
2727
|
+
`No tracked instance for runtime fallback ${serviceName}/${serviceInstanceId}`,
|
|
2728
|
+
{
|
|
2729
|
+
target: {
|
|
2730
|
+
serviceName,
|
|
2731
|
+
serviceInstanceId
|
|
2732
|
+
},
|
|
2733
|
+
instance: this.summarizeInstanceForRuntimeStatusFallback(instance),
|
|
2734
|
+
directStatusCheck: directStatusCheck.diagnostic,
|
|
2735
|
+
inquiry: {
|
|
2736
|
+
meta: {},
|
|
2737
|
+
reportTargets: []
|
|
2738
|
+
}
|
|
2633
2739
|
}
|
|
2634
|
-
|
|
2740
|
+
);
|
|
2635
2741
|
}
|
|
2742
|
+
this.lastHeartbeatAtByInstance.set(serviceInstanceId, Date.now());
|
|
2743
|
+
this.missedHeartbeatsByInstance.set(serviceInstanceId, 0);
|
|
2744
|
+
return {
|
|
2745
|
+
report: directStatusCheck.report,
|
|
2746
|
+
inquiryMeta: {
|
|
2747
|
+
inquiry: META_RUNTIME_STATUS_INTENT,
|
|
2748
|
+
responded: 1,
|
|
2749
|
+
failed: 0,
|
|
2750
|
+
timedOut: 0,
|
|
2751
|
+
pending: 0,
|
|
2752
|
+
directStatusCheck: true
|
|
2753
|
+
}
|
|
2754
|
+
};
|
|
2636
2755
|
}
|
|
2637
2756
|
const inquiryResult = await CadenzaService.inquire(
|
|
2638
2757
|
META_RUNTIME_STATUS_INTENT,
|
|
@@ -2654,13 +2773,37 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2654
2773
|
serviceInstanceId
|
|
2655
2774
|
);
|
|
2656
2775
|
if (!report) {
|
|
2657
|
-
throw
|
|
2658
|
-
`No runtime status report for ${serviceName}/${serviceInstanceId}
|
|
2776
|
+
throw this.createRuntimeStatusFallbackError(
|
|
2777
|
+
`No runtime status report for ${serviceName}/${serviceInstanceId}`,
|
|
2778
|
+
{
|
|
2779
|
+
target: {
|
|
2780
|
+
serviceName,
|
|
2781
|
+
serviceInstanceId
|
|
2782
|
+
},
|
|
2783
|
+
instance: this.summarizeInstanceForRuntimeStatusFallback(instance),
|
|
2784
|
+
directStatusCheck: directStatusCheck.diagnostic,
|
|
2785
|
+
inquiry: {
|
|
2786
|
+
meta: inquiryResult.__inquiryMeta && typeof inquiryResult.__inquiryMeta === "object" ? inquiryResult.__inquiryMeta : {},
|
|
2787
|
+
reportTargets: this.summarizeRuntimeStatusInquiryReports(inquiryResult)
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2659
2790
|
);
|
|
2660
2791
|
}
|
|
2661
2792
|
if (!this.applyRuntimeStatusReport(report)) {
|
|
2662
|
-
throw
|
|
2663
|
-
`No tracked instance for runtime fallback ${serviceName}/${serviceInstanceId}
|
|
2793
|
+
throw this.createRuntimeStatusFallbackError(
|
|
2794
|
+
`No tracked instance for runtime fallback ${serviceName}/${serviceInstanceId}`,
|
|
2795
|
+
{
|
|
2796
|
+
target: {
|
|
2797
|
+
serviceName,
|
|
2798
|
+
serviceInstanceId
|
|
2799
|
+
},
|
|
2800
|
+
instance: this.summarizeInstanceForRuntimeStatusFallback(instance),
|
|
2801
|
+
directStatusCheck: directStatusCheck.diagnostic,
|
|
2802
|
+
inquiry: {
|
|
2803
|
+
meta: inquiryResult.__inquiryMeta && typeof inquiryResult.__inquiryMeta === "object" ? inquiryResult.__inquiryMeta : {},
|
|
2804
|
+
reportTargets: this.summarizeRuntimeStatusInquiryReports(inquiryResult)
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2664
2807
|
);
|
|
2665
2808
|
}
|
|
2666
2809
|
this.lastHeartbeatAtByInstance.set(serviceInstanceId, Date.now());
|
|
@@ -2672,11 +2815,23 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2672
2815
|
}
|
|
2673
2816
|
async requestRuntimeStatusViaRest(instance, serviceName, serviceInstanceId) {
|
|
2674
2817
|
if (typeof globalThis.fetch !== "function") {
|
|
2675
|
-
return
|
|
2818
|
+
return {
|
|
2819
|
+
report: null,
|
|
2820
|
+
diagnostic: {
|
|
2821
|
+
attempted: false,
|
|
2822
|
+
outcome: "fetch_unavailable"
|
|
2823
|
+
}
|
|
2824
|
+
};
|
|
2676
2825
|
}
|
|
2677
2826
|
const transport = this.getRouteableTransport(instance, "rest");
|
|
2678
2827
|
if (!transport) {
|
|
2679
|
-
return
|
|
2828
|
+
return {
|
|
2829
|
+
report: null,
|
|
2830
|
+
diagnostic: {
|
|
2831
|
+
attempted: false,
|
|
2832
|
+
outcome: "no_rest_transport"
|
|
2833
|
+
}
|
|
2834
|
+
};
|
|
2680
2835
|
}
|
|
2681
2836
|
const controller = typeof AbortController === "function" ? new AbortController() : null;
|
|
2682
2837
|
const timeoutId = controller ? setTimeout(() => controller.abort(), this.runtimeStatusFallbackTimeoutMs) : null;
|
|
@@ -2686,7 +2841,16 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2686
2841
|
signal: controller?.signal
|
|
2687
2842
|
});
|
|
2688
2843
|
if ("ok" in response && response.ok === false) {
|
|
2689
|
-
return
|
|
2844
|
+
return {
|
|
2845
|
+
report: null,
|
|
2846
|
+
diagnostic: {
|
|
2847
|
+
attempted: true,
|
|
2848
|
+
outcome: "http_error",
|
|
2849
|
+
transport: this.summarizeTransportForDebug(transport),
|
|
2850
|
+
responseStatus: typeof response.status === "number" ? response.status : void 0,
|
|
2851
|
+
responseStatusText: typeof response.statusText === "string" ? response.statusText : void 0
|
|
2852
|
+
}
|
|
2853
|
+
};
|
|
2690
2854
|
}
|
|
2691
2855
|
const payload = typeof response.json === "function" ? await response.json() : response;
|
|
2692
2856
|
const report = this.normalizeRuntimeStatusReport({
|
|
@@ -2696,14 +2860,46 @@ var ServiceRegistry = class _ServiceRegistry {
|
|
|
2696
2860
|
transportProtocols: payload?.transportProtocols ?? transport.protocols
|
|
2697
2861
|
});
|
|
2698
2862
|
if (!report) {
|
|
2699
|
-
return
|
|
2863
|
+
return {
|
|
2864
|
+
report: null,
|
|
2865
|
+
diagnostic: {
|
|
2866
|
+
attempted: true,
|
|
2867
|
+
outcome: "invalid_report",
|
|
2868
|
+
transport: this.summarizeTransportForDebug(transport),
|
|
2869
|
+
payloadKeys: payload && typeof payload === "object" ? Object.keys(payload).sort() : []
|
|
2870
|
+
}
|
|
2871
|
+
};
|
|
2700
2872
|
}
|
|
2701
2873
|
if (report.serviceName !== serviceName || report.serviceInstanceId !== serviceInstanceId) {
|
|
2702
|
-
return
|
|
2874
|
+
return {
|
|
2875
|
+
report: null,
|
|
2876
|
+
diagnostic: {
|
|
2877
|
+
attempted: true,
|
|
2878
|
+
outcome: "identity_mismatch",
|
|
2879
|
+
transport: this.summarizeTransportForDebug(transport),
|
|
2880
|
+
payloadServiceName: report.serviceName,
|
|
2881
|
+
payloadServiceInstanceId: report.serviceInstanceId
|
|
2882
|
+
}
|
|
2883
|
+
};
|
|
2703
2884
|
}
|
|
2704
|
-
return
|
|
2705
|
-
|
|
2706
|
-
|
|
2885
|
+
return {
|
|
2886
|
+
report,
|
|
2887
|
+
diagnostic: {
|
|
2888
|
+
attempted: true,
|
|
2889
|
+
outcome: "matched",
|
|
2890
|
+
transport: this.summarizeTransportForDebug(transport)
|
|
2891
|
+
}
|
|
2892
|
+
};
|
|
2893
|
+
} catch (error) {
|
|
2894
|
+
return {
|
|
2895
|
+
report: null,
|
|
2896
|
+
diagnostic: {
|
|
2897
|
+
attempted: true,
|
|
2898
|
+
outcome: "fetch_error",
|
|
2899
|
+
transport: this.summarizeTransportForDebug(transport),
|
|
2900
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2901
|
+
}
|
|
2902
|
+
};
|
|
2707
2903
|
} finally {
|
|
2708
2904
|
if (timeoutId) {
|
|
2709
2905
|
clearTimeout(timeoutId);
|
|
@@ -9409,6 +9605,7 @@ var CadenzaService = class {
|
|
|
9409
9605
|
isBlocked: false,
|
|
9410
9606
|
health: {},
|
|
9411
9607
|
isFrontend: false,
|
|
9608
|
+
isBootstrapPlaceholder: true,
|
|
9412
9609
|
transports: resolvedBootstrapEndpoint ? [
|
|
9413
9610
|
this.createBootstrapTransport(
|
|
9414
9611
|
"cadenza-db",
|
|
@@ -9436,6 +9633,7 @@ var CadenzaService = class {
|
|
|
9436
9633
|
isBlocked: false,
|
|
9437
9634
|
health: {},
|
|
9438
9635
|
isFrontend: false,
|
|
9636
|
+
isBootstrapPlaceholder: true,
|
|
9439
9637
|
transports: relatedTransport ? [
|
|
9440
9638
|
{
|
|
9441
9639
|
uuid: `${service[0]}-${relatedTransport.role}`,
|