@cadenza.io/service 2.17.5 → 2.17.7

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/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
  }
@@ -1236,9 +1243,23 @@ var ServiceRegistry = class _ServiceRegistry {
1236
1243
  (ctx, emit) => {
1237
1244
  const { serviceName, serviceInstanceId } = ctx;
1238
1245
  const serviceInstances = this.instances.get(serviceName);
1239
- const instance = serviceInstances?.find(
1246
+ let instance = serviceInstances?.find(
1240
1247
  (i) => i.uuid === serviceInstanceId
1241
1248
  );
1249
+ if (!instance && serviceName && serviceInstanceId) {
1250
+ const bootstrapPlaceholder = serviceInstances?.find(
1251
+ (candidate) => candidate.isBootstrapPlaceholder && (!ctx.serviceTransportId || candidate.transports.some(
1252
+ (transport) => transport.uuid === ctx.serviceTransportId
1253
+ ))
1254
+ );
1255
+ if (bootstrapPlaceholder) {
1256
+ instance = this.adoptBootstrapPlaceholderInstanceId(
1257
+ serviceName,
1258
+ bootstrapPlaceholder.uuid,
1259
+ serviceInstanceId
1260
+ );
1261
+ }
1262
+ }
1242
1263
  if (!instance) {
1243
1264
  return false;
1244
1265
  }
@@ -2310,6 +2331,7 @@ var ServiceRegistry = class _ServiceRegistry {
2310
2331
  reportedAt: instance?.reportedAt ?? null,
2311
2332
  isDatabase: instance?.isDatabase,
2312
2333
  isFrontend: instance?.isFrontend,
2334
+ isBootstrapPlaceholder: instance?.isBootstrapPlaceholder,
2313
2335
  transports: (instance?.transports ?? []).map((transport) => ({
2314
2336
  uuid: transport.uuid,
2315
2337
  role: transport.role,
@@ -2476,6 +2498,105 @@ var ServiceRegistry = class _ServiceRegistry {
2476
2498
  this.missedHeartbeatsByInstance.delete(serviceInstanceId);
2477
2499
  this.runtimeStatusFallbackInFlightByInstance.delete(serviceInstanceId);
2478
2500
  }
2501
+ reconcileBootstrapPlaceholderInstance(serviceName, resolvedInstanceId, emit) {
2502
+ const instances = this.instances.get(serviceName);
2503
+ if (!instances?.length) {
2504
+ return;
2505
+ }
2506
+ const placeholders = instances.filter(
2507
+ (instance) => instance.uuid !== resolvedInstanceId && instance.isBootstrapPlaceholder
2508
+ );
2509
+ if (!placeholders.length) {
2510
+ return;
2511
+ }
2512
+ for (const placeholder of placeholders) {
2513
+ const wasDependee = this.dependeeByInstance.has(placeholder.uuid);
2514
+ const requiredForReadiness = this.readinessDependeeByInstance.has(
2515
+ placeholder.uuid
2516
+ );
2517
+ for (const transport of placeholder.transports) {
2518
+ const transportKey = buildTransportClientKey(transport);
2519
+ emit(`meta.socket_shutdown_requested:${transportKey}`, {});
2520
+ emit(`meta.fetch.destroy_requested:${transportKey}`, {});
2521
+ }
2522
+ this.unregisterDependee(placeholder.uuid, serviceName);
2523
+ if (wasDependee) {
2524
+ this.registerDependee(serviceName, resolvedInstanceId, {
2525
+ requiredForReadiness
2526
+ });
2527
+ }
2528
+ }
2529
+ this.instances.set(
2530
+ serviceName,
2531
+ instances.filter((instance) => !instance.isBootstrapPlaceholder)
2532
+ );
2533
+ }
2534
+ adoptBootstrapPlaceholderInstanceId(serviceName, placeholderInstanceId, resolvedInstanceId) {
2535
+ if (!serviceName || !placeholderInstanceId || !resolvedInstanceId) {
2536
+ return void 0;
2537
+ }
2538
+ const instances = this.instances.get(serviceName);
2539
+ if (!instances?.length) {
2540
+ return void 0;
2541
+ }
2542
+ const resolvedInstance = instances.find(
2543
+ (instance) => instance.uuid === resolvedInstanceId
2544
+ );
2545
+ if (resolvedInstance) {
2546
+ return resolvedInstance;
2547
+ }
2548
+ const placeholder = instances.find(
2549
+ (instance) => instance.uuid === placeholderInstanceId && instance.isBootstrapPlaceholder
2550
+ );
2551
+ if (!placeholder) {
2552
+ return void 0;
2553
+ }
2554
+ const wasDependee = this.dependeeByInstance.has(placeholderInstanceId);
2555
+ const dependeeServiceName = this.dependeeByInstance.get(placeholderInstanceId) ?? serviceName;
2556
+ const requiredForReadiness = this.readinessDependeeByInstance.has(
2557
+ placeholderInstanceId
2558
+ );
2559
+ const lastHeartbeatAt = this.lastHeartbeatAtByInstance.get(placeholderInstanceId) ?? Date.now();
2560
+ const missedHeartbeats = this.missedHeartbeatsByInstance.get(placeholderInstanceId) ?? 0;
2561
+ const inFlight = this.runtimeStatusFallbackInFlightByInstance.has(
2562
+ placeholderInstanceId
2563
+ );
2564
+ this.dependeeByInstance.delete(placeholderInstanceId);
2565
+ this.readinessDependeeByInstance.delete(placeholderInstanceId);
2566
+ this.lastHeartbeatAtByInstance.delete(placeholderInstanceId);
2567
+ this.missedHeartbeatsByInstance.delete(placeholderInstanceId);
2568
+ this.runtimeStatusFallbackInFlightByInstance.delete(placeholderInstanceId);
2569
+ placeholder.uuid = resolvedInstanceId;
2570
+ placeholder.isBootstrapPlaceholder = false;
2571
+ placeholder.transports = placeholder.transports.map((transport) => ({
2572
+ ...transport,
2573
+ serviceInstanceId: resolvedInstanceId
2574
+ }));
2575
+ if (wasDependee) {
2576
+ this.dependeeByInstance.set(resolvedInstanceId, dependeeServiceName);
2577
+ if (this.dependeesByService.has(dependeeServiceName)) {
2578
+ this.dependeesByService.get(dependeeServiceName).delete(
2579
+ placeholderInstanceId
2580
+ );
2581
+ this.dependeesByService.get(dependeeServiceName).add(resolvedInstanceId);
2582
+ }
2583
+ this.lastHeartbeatAtByInstance.set(resolvedInstanceId, lastHeartbeatAt);
2584
+ this.missedHeartbeatsByInstance.set(resolvedInstanceId, missedHeartbeats);
2585
+ }
2586
+ if (requiredForReadiness) {
2587
+ this.readinessDependeeByInstance.set(resolvedInstanceId, serviceName);
2588
+ if (this.readinessDependeesByService.has(serviceName)) {
2589
+ this.readinessDependeesByService.get(serviceName).delete(
2590
+ placeholderInstanceId
2591
+ );
2592
+ this.readinessDependeesByService.get(serviceName).add(resolvedInstanceId);
2593
+ }
2594
+ }
2595
+ if (inFlight) {
2596
+ this.runtimeStatusFallbackInFlightByInstance.add(resolvedInstanceId);
2597
+ }
2598
+ return placeholder;
2599
+ }
2479
2600
  getHeartbeatMisses(serviceInstanceId, now = Date.now()) {
2480
2601
  const observedMisses = this.missedHeartbeatsByInstance.get(serviceInstanceId) ?? 0;
2481
2602
  const lastHeartbeatAt = this.lastHeartbeatAtByInstance.get(serviceInstanceId) ?? 0;
@@ -9564,6 +9685,7 @@ var CadenzaService = class {
9564
9685
  isBlocked: false,
9565
9686
  health: {},
9566
9687
  isFrontend: false,
9688
+ isBootstrapPlaceholder: true,
9567
9689
  transports: resolvedBootstrapEndpoint ? [
9568
9690
  this.createBootstrapTransport(
9569
9691
  "cadenza-db",
@@ -9591,6 +9713,7 @@ var CadenzaService = class {
9591
9713
  isBlocked: false,
9592
9714
  health: {},
9593
9715
  isFrontend: false,
9716
+ isBootstrapPlaceholder: true,
9594
9717
  transports: relatedTransport ? [
9595
9718
  {
9596
9719
  uuid: `${service[0]}-${relatedTransport.role}`,