@spine-event-engine/server 2.0.0-snapshot.24 → 2.0.0-snapshot.25
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/README.md +38 -11
- package/REFERENCE.md +201 -130
- package/dist/agent/agent-acceptance-receipts.d.ts +69 -0
- package/dist/agent/agent-acceptance-receipts.d.ts.map +1 -0
- package/dist/agent/agent-acceptance-receipts.js +198 -0
- package/dist/agent/agent-acceptance-receipts.js.map +1 -0
- package/dist/agent/agent-execution-capacity.d.ts +37 -9
- package/dist/agent/agent-execution-capacity.d.ts.map +1 -1
- package/dist/agent/agent-execution-capacity.js +73 -15
- package/dist/agent/agent-execution-capacity.js.map +1 -1
- package/dist/agent/agent-history.d.ts +15 -10
- package/dist/agent/agent-history.d.ts.map +1 -1
- package/dist/agent/agent-history.js +26 -14
- package/dist/agent/agent-history.js.map +1 -1
- package/dist/agent/agent-live-ai-audit.d.ts +95 -0
- package/dist/agent/agent-live-ai-audit.d.ts.map +1 -0
- package/dist/agent/agent-live-ai-audit.js +290 -0
- package/dist/agent/agent-live-ai-audit.js.map +1 -0
- package/dist/agent/agent-live-ai-runtime.d.ts +300 -0
- package/dist/agent/agent-live-ai-runtime.d.ts.map +1 -0
- package/dist/agent/agent-live-ai-runtime.js +611 -0
- package/dist/agent/agent-live-ai-runtime.js.map +1 -0
- package/dist/agent/agent-live-audit.d.ts +67 -0
- package/dist/agent/agent-live-audit.d.ts.map +1 -0
- package/dist/agent/agent-live-audit.js +121 -0
- package/dist/agent/agent-live-audit.js.map +1 -0
- package/dist/agent/agent-live-budget.d.ts +84 -0
- package/dist/agent/agent-live-budget.d.ts.map +1 -0
- package/dist/agent/agent-live-budget.js +161 -0
- package/dist/agent/agent-live-budget.js.map +1 -0
- package/dist/agent/agent-live-fault.d.ts +18 -0
- package/dist/agent/agent-live-fault.d.ts.map +1 -0
- package/dist/agent/{agent-execution-fault.js → agent-live-fault.js} +7 -7
- package/dist/agent/agent-live-fault.js.map +1 -0
- package/dist/agent/agent-live-inputs.d.ts +74 -0
- package/dist/agent/agent-live-inputs.d.ts.map +1 -0
- package/dist/{bus/saved-dispatcher-binding.js → agent/agent-live-inputs.js} +2 -14
- package/dist/agent/agent-live-inputs.js.map +1 -0
- package/dist/agent/agent-live-interaction-events.d.ts +46 -0
- package/dist/agent/agent-live-interaction-events.d.ts.map +1 -0
- package/dist/agent/agent-live-interaction-events.js +104 -0
- package/dist/agent/agent-live-interaction-events.js.map +1 -0
- package/dist/agent/agent-live-mcp-controls.d.ts +129 -0
- package/dist/agent/agent-live-mcp-controls.d.ts.map +1 -0
- package/dist/agent/agent-live-mcp-controls.js +228 -0
- package/dist/agent/agent-live-mcp-controls.js.map +1 -0
- package/dist/agent/agent-live-mcp-host.d.ts +88 -0
- package/dist/agent/agent-live-mcp-host.d.ts.map +1 -0
- package/dist/agent/{agent-mcp-host.js → agent-live-mcp-host.js} +1 -1
- package/dist/agent/agent-live-mcp-host.js.map +1 -0
- package/dist/agent/{agent-mcp-runtime.d.ts → agent-live-mcp-runtime.d.ts} +6 -6
- package/dist/agent/agent-live-mcp-runtime.d.ts.map +1 -0
- package/dist/agent/{agent-mcp-runtime.js → agent-live-mcp-runtime.js} +13 -42
- package/dist/agent/agent-live-mcp-runtime.js.map +1 -0
- package/dist/agent/agent-live-read-runtime.d.ts +61 -0
- package/dist/agent/agent-live-read-runtime.d.ts.map +1 -0
- package/dist/agent/agent-live-read-runtime.js +121 -0
- package/dist/agent/agent-live-read-runtime.js.map +1 -0
- package/dist/agent/agent-model-selection.d.ts +21 -34
- package/dist/agent/agent-model-selection.d.ts.map +1 -1
- package/dist/agent/agent-model-selection.js +61 -78
- package/dist/agent/agent-model-selection.js.map +1 -1
- package/dist/bus/command-bus.d.ts +14 -18
- package/dist/bus/command-bus.d.ts.map +1 -1
- package/dist/bus/command-bus.js +31 -48
- package/dist/bus/command-bus.js.map +1 -1
- package/dist/bus/event-bus.d.ts +17 -4
- package/dist/bus/event-bus.d.ts.map +1 -1
- package/dist/bus/event-bus.js +42 -12
- package/dist/bus/event-bus.js.map +1 -1
- package/dist/context/bounded-context.d.ts +140 -87
- package/dist/context/bounded-context.d.ts.map +1 -1
- package/dist/context/bounded-context.js +702 -329
- package/dist/context/bounded-context.js.map +1 -1
- package/dist/context/entity-inbox.d.ts +7 -2
- package/dist/context/entity-inbox.d.ts.map +1 -1
- package/dist/context/entity-inbox.js +22 -13
- package/dist/context/entity-inbox.js.map +1 -1
- package/dist/context/local-inbox-handoff.d.ts +34 -34
- package/dist/context/local-inbox-handoff.d.ts.map +1 -1
- package/dist/context/local-inbox-handoff.js +108 -150
- package/dist/context/local-inbox-handoff.js.map +1 -1
- package/dist/context/projection-handoff.d.ts +2 -2
- package/dist/context/projection-handoff.d.ts.map +1 -1
- package/dist/context/projection-handoff.js +10 -8
- package/dist/context/projection-handoff.js.map +1 -1
- package/dist/context/tenant-index.d.ts +36 -31
- package/dist/context/tenant-index.d.ts.map +1 -1
- package/dist/context/tenant-index.js +123 -125
- package/dist/context/tenant-index.js.map +1 -1
- package/dist/context/tenant-unknown-error.d.ts +33 -0
- package/dist/context/tenant-unknown-error.d.ts.map +1 -0
- package/dist/context/tenant-unknown-error.js +75 -0
- package/dist/context/tenant-unknown-error.js.map +1 -0
- package/dist/delivery/agent-delivery-scope.d.ts +66 -0
- package/dist/delivery/agent-delivery-scope.d.ts.map +1 -0
- package/dist/delivery/agent-delivery-scope.js +44 -0
- package/dist/delivery/agent-delivery-scope.js.map +1 -0
- package/dist/delivery/delivery-builder.d.ts +25 -1
- package/dist/delivery/delivery-builder.d.ts.map +1 -1
- package/dist/delivery/delivery-builder.js +89 -0
- package/dist/delivery/delivery-builder.js.map +1 -1
- package/dist/delivery/delivery-monitor.d.ts +1 -1
- package/dist/delivery/delivery-monitor.js +1 -1
- package/dist/delivery/delivery-run-control.d.ts +6 -0
- package/dist/delivery/delivery-run-control.d.ts.map +1 -1
- package/dist/delivery/delivery-run-control.js +10 -0
- package/dist/delivery/delivery-run-control.js.map +1 -1
- package/dist/delivery/delivery-supervisor.d.ts.map +1 -1
- package/dist/delivery/delivery-supervisor.js +28 -4
- package/dist/delivery/delivery-supervisor.js.map +1 -1
- package/dist/delivery/delivery-tenant.d.ts +17 -0
- package/dist/delivery/delivery-tenant.d.ts.map +1 -0
- package/dist/delivery/delivery-tenant.js +50 -0
- package/dist/delivery/delivery-tenant.js.map +1 -0
- package/dist/delivery/delivery.d.ts +96 -2
- package/dist/delivery/delivery.d.ts.map +1 -1
- package/dist/delivery/delivery.js +693 -53
- package/dist/delivery/delivery.js.map +1 -1
- package/dist/delivery/inbox-records.d.ts.map +1 -1
- package/dist/delivery/inbox-records.js +9 -16
- package/dist/delivery/inbox-records.js.map +1 -1
- package/dist/delivery/inbox-storage.d.ts +6 -0
- package/dist/delivery/inbox-storage.d.ts.map +1 -1
- package/dist/delivery/inbox-storage.js +43 -6
- package/dist/delivery/inbox-storage.js.map +1 -1
- package/dist/delivery/inbox.d.ts.map +1 -1
- package/dist/delivery/inbox.js +3 -2
- package/dist/delivery/inbox.js.map +1 -1
- package/dist/delivery/reception-observation.d.ts +12 -4
- package/dist/delivery/reception-observation.d.ts.map +1 -1
- package/dist/delivery/reception-observation.js +14 -3
- package/dist/delivery/reception-observation.js.map +1 -1
- package/dist/delivery/sharded-work-registry.d.ts +6 -0
- package/dist/delivery/sharded-work-registry.d.ts.map +1 -1
- package/dist/delivery/sharded-work-registry.js +41 -4
- package/dist/delivery/sharded-work-registry.js.map +1 -1
- package/dist/entity/entity-storage-descriptor.d.ts.map +1 -1
- package/dist/entity/entity-storage-descriptor.js +7 -4
- package/dist/entity/entity-storage-descriptor.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/integration/external-messages.d.ts.map +1 -1
- package/dist/integration/external-messages.js +9 -15
- package/dist/integration/external-messages.js.map +1 -1
- package/dist/integration/integration-broker.d.ts.map +1 -1
- package/dist/integration/integration-broker.js +112 -6
- package/dist/integration/integration-broker.js.map +1 -1
- package/dist/integration/third-party-context.d.ts.map +1 -1
- package/dist/integration/third-party-context.js +7 -10
- package/dist/integration/third-party-context.js.map +1 -1
- package/dist/repository/primitive-id.js +26 -11
- package/dist/repository/primitive-id.js.map +1 -1
- package/dist/repository/repository.d.ts +32 -60
- package/dist/repository/repository.d.ts.map +1 -1
- package/dist/repository/repository.js +1446 -1787
- package/dist/repository/repository.js.map +1 -1
- package/dist/runtime/runtime.d.ts +13 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +18 -0
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/signal-metadata.d.ts.map +1 -1
- package/dist/runtime/signal-metadata.js +6 -6
- package/dist/runtime/signal-metadata.js.map +1 -1
- package/dist/runtime/signal-publisher.d.ts +0 -6
- package/dist/runtime/signal-publisher.d.ts.map +1 -1
- package/dist/runtime/signal-publisher.js +1 -9
- package/dist/runtime/signal-publisher.js.map +1 -1
- package/dist/runtime/standalone-handler-runtime.d.ts +0 -7
- package/dist/runtime/standalone-handler-runtime.d.ts.map +1 -1
- package/dist/runtime/standalone-handler-runtime.js +13 -99
- package/dist/runtime/standalone-handler-runtime.js.map +1 -1
- package/dist/server/managed-delivery-gate.d.ts +34 -0
- package/dist/server/managed-delivery-gate.d.ts.map +1 -0
- package/dist/server/managed-delivery-gate.js +70 -0
- package/dist/server/managed-delivery-gate.js.map +1 -0
- package/dist/server/managed-server-application.d.ts.map +1 -1
- package/dist/server/managed-server-application.js +7 -4
- package/dist/server/managed-server-application.js.map +1 -1
- package/dist/server/server-environment.d.ts +203 -25
- package/dist/server/server-environment.d.ts.map +1 -1
- package/dist/server/server-environment.js +661 -133
- package/dist/server/server-environment.js.map +1 -1
- package/dist/server/server-log.d.ts +7 -0
- package/dist/server/server-log.d.ts.map +1 -1
- package/dist/server/server-log.js +14 -1
- package/dist/server/server-log.js.map +1 -1
- package/dist/server/server.d.ts +18 -32
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +50 -204
- package/dist/server/server.js.map +1 -1
- package/dist/services/spine-services.d.ts +1 -1
- package/dist/services/spine-services.d.ts.map +1 -1
- package/dist/services/spine-services.js +236 -335
- package/dist/services/spine-services.js.map +1 -1
- package/dist/stand/event-origin-filter.js +3 -3
- package/dist/stand/event-origin-filter.js.map +1 -1
- package/dist/stand/stand.d.ts +14 -0
- package/dist/stand/stand.d.ts.map +1 -1
- package/dist/stand/stand.js +53 -9
- package/dist/stand/stand.js.map +1 -1
- package/dist/stand/subscription-observer.d.ts.map +1 -1
- package/dist/stand/subscription-observer.js +54 -40
- package/dist/stand/subscription-observer.js.map +1 -1
- package/dist/stand/subscription-registry.d.ts +6 -2
- package/dist/stand/subscription-registry.d.ts.map +1 -1
- package/dist/stand/subscription-registry.js +15 -11
- package/dist/stand/subscription-registry.js.map +1 -1
- package/dist/stand/subscription-runtime.d.ts +5 -3
- package/dist/stand/subscription-runtime.d.ts.map +1 -1
- package/dist/stand/subscription-runtime.js +52 -9
- package/dist/stand/subscription-runtime.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +4 -3
- package/dist/testing/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -14
- package/dist/agent/agent-admission.d.ts +0 -80
- package/dist/agent/agent-admission.d.ts.map +0 -1
- package/dist/agent/agent-admission.js +0 -127
- package/dist/agent/agent-admission.js.map +0 -1
- package/dist/agent/agent-ai-runtime.d.ts +0 -76
- package/dist/agent/agent-ai-runtime.d.ts.map +0 -1
- package/dist/agent/agent-ai-runtime.js +0 -1269
- package/dist/agent/agent-ai-runtime.js.map +0 -1
- package/dist/agent/agent-execution-fault.d.ts +0 -18
- package/dist/agent/agent-execution-fault.d.ts.map +0 -1
- package/dist/agent/agent-execution-fault.js.map +0 -1
- package/dist/agent/agent-execution-session.d.ts +0 -103
- package/dist/agent/agent-execution-session.d.ts.map +0 -1
- package/dist/agent/agent-execution-session.js +0 -238
- package/dist/agent/agent-execution-session.js.map +0 -1
- package/dist/agent/agent-interaction-audit.d.ts +0 -58
- package/dist/agent/agent-interaction-audit.d.ts.map +0 -1
- package/dist/agent/agent-interaction-audit.js +0 -114
- package/dist/agent/agent-interaction-audit.js.map +0 -1
- package/dist/agent/agent-interaction-events.d.ts +0 -40
- package/dist/agent/agent-interaction-events.d.ts.map +0 -1
- package/dist/agent/agent-interaction-events.js +0 -129
- package/dist/agent/agent-interaction-events.js.map +0 -1
- package/dist/agent/agent-mcp-budget.d.ts +0 -125
- package/dist/agent/agent-mcp-budget.d.ts.map +0 -1
- package/dist/agent/agent-mcp-budget.js +0 -566
- package/dist/agent/agent-mcp-budget.js.map +0 -1
- package/dist/agent/agent-mcp-host.d.ts +0 -125
- package/dist/agent/agent-mcp-host.d.ts.map +0 -1
- package/dist/agent/agent-mcp-host.js.map +0 -1
- package/dist/agent/agent-mcp-runtime.d.ts.map +0 -1
- package/dist/agent/agent-mcp-runtime.js.map +0 -1
- package/dist/agent/agent-read-runtime.d.ts +0 -70
- package/dist/agent/agent-read-runtime.d.ts.map +0 -1
- package/dist/agent/agent-read-runtime.js +0 -320
- package/dist/agent/agent-read-runtime.js.map +0 -1
- package/dist/agent/agent-revisions.d.ts +0 -35
- package/dist/agent/agent-revisions.d.ts.map +0 -1
- package/dist/agent/agent-revisions.js +0 -133
- package/dist/agent/agent-revisions.js.map +0 -1
- package/dist/agent/agent-scheduler.d.ts +0 -99
- package/dist/agent/agent-scheduler.d.ts.map +0 -1
- package/dist/agent/agent-scheduler.js +0 -398
- package/dist/agent/agent-scheduler.js.map +0 -1
- package/dist/bus/saved-dispatcher-binding.d.ts +0 -53
- package/dist/bus/saved-dispatcher-binding.d.ts.map +0 -1
- package/dist/bus/saved-dispatcher-binding.js.map +0 -1
- package/dist/delivery/delivery-run-coordinator.d.ts +0 -218
- package/dist/delivery/delivery-run-coordinator.d.ts.map +0 -1
- package/dist/delivery/delivery-run-coordinator.js +0 -609
- package/dist/delivery/delivery-run-coordinator.js.map +0 -1
- package/dist/delivery/parked-delivery-obligations.d.ts +0 -182
- package/dist/delivery/parked-delivery-obligations.d.ts.map +0 -1
- package/dist/delivery/parked-delivery-obligations.js +0 -390
- package/dist/delivery/parked-delivery-obligations.js.map +0 -1
- package/dist/server/environment-attachment.d.ts +0 -356
- package/dist/server/environment-attachment.d.ts.map +0 -1
- package/dist/server/environment-attachment.js +0 -2062
- package/dist/server/environment-attachment.js.map +0 -1
- package/dist/server/environment-delivery-records.d.ts +0 -77
- package/dist/server/environment-delivery-records.d.ts.map +0 -1
- package/dist/server/environment-delivery-records.js +0 -282
- package/dist/server/environment-delivery-records.js.map +0 -1
- package/dist/server/environment-delivery-worker.d.ts +0 -161
- package/dist/server/environment-delivery-worker.d.ts.map +0 -1
- package/dist/server/environment-delivery-worker.js +0 -973
- package/dist/server/environment-delivery-worker.js.map +0 -1
|
@@ -1,973 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2026, CodeMatters. All rights reserved.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
5
|
-
* in compliance with the License. You may obtain a copy of the License at
|
|
6
|
-
*
|
|
7
|
-
* https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
*
|
|
9
|
-
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
10
|
-
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
11
|
-
* or implied. See the License for the specific language governing permissions and limitations under
|
|
12
|
-
* the License.
|
|
13
|
-
*/
|
|
14
|
-
var _a;
|
|
15
|
-
import {} from "@spine-event-engine/storage";
|
|
16
|
-
import { TenantBoundary } from "@spine-event-engine/storage/provider";
|
|
17
|
-
import { fromBinary } from "@bufbuild/protobuf";
|
|
18
|
-
import { CommandSchema, EventSchema } from "@spine-event-engine/proto";
|
|
19
|
-
import { deliveryRunWorkers, } from "../delivery/delivery-run-coordinator.js";
|
|
20
|
-
import { DeliveryBuilder, UniformAcrossAllShards } from "../delivery/delivery-builder.js";
|
|
21
|
-
import { Delivery, } from "../delivery/delivery.js";
|
|
22
|
-
import { receptionObservation } from "../delivery/reception-observation.js";
|
|
23
|
-
import { DeliverySupervisor, deliverySupervisorAccess, } from "../delivery/delivery-supervisor.js";
|
|
24
|
-
import { DeliveryWorker } from "../delivery/delivery-worker.js";
|
|
25
|
-
import { ShardIndex } from "../delivery/shard-index.js";
|
|
26
|
-
const managedChild = process.env.SPINE_MANAGED_SERVER_CHILD === "true";
|
|
27
|
-
let cancelManagedDelivery = false;
|
|
28
|
-
let managedDeliveryActivated = !managedChild;
|
|
29
|
-
const waitingManagedSupervisors = new Set();
|
|
30
|
-
/**
|
|
31
|
-
* Controls private managed-child Delivery admission.
|
|
32
|
-
*
|
|
33
|
-
* @internal
|
|
34
|
-
*/
|
|
35
|
-
export const environmentDeliveryWorkerAccess = Object.freeze({
|
|
36
|
-
activateManagedChild() {
|
|
37
|
-
managedDeliveryActivated = true;
|
|
38
|
-
for (const start of waitingManagedSupervisors)
|
|
39
|
-
start();
|
|
40
|
-
waitingManagedSupervisors.clear();
|
|
41
|
-
},
|
|
42
|
-
cancelManagedChild() {
|
|
43
|
-
cancelManagedDelivery = true;
|
|
44
|
-
waitingManagedSupervisors.clear();
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
|
-
/**
|
|
48
|
-
* Routes each owner-partitioned obligation to its exact runtime worker.
|
|
49
|
-
*
|
|
50
|
-
* @internal
|
|
51
|
-
*/
|
|
52
|
-
export class EnvironmentDeliveryWorker {
|
|
53
|
-
#workers = new Map();
|
|
54
|
-
#supervisor;
|
|
55
|
-
#stoppedWorkers = new Set();
|
|
56
|
-
#stoppedSupervisors = new Set();
|
|
57
|
-
#stoppedOwners = new Set();
|
|
58
|
-
#createWorker;
|
|
59
|
-
#nodeId;
|
|
60
|
-
#ports;
|
|
61
|
-
/**
|
|
62
|
-
* Creates an environment delivery worker.
|
|
63
|
-
*
|
|
64
|
-
* @param options Optionally supplies a worker factory for lifecycle tests.
|
|
65
|
-
*/
|
|
66
|
-
constructor(options = {}) {
|
|
67
|
-
this.#createWorker = options.createWorker ?? EnvironmentDeliveryValues.createWorker;
|
|
68
|
-
this.#ports = options.ports;
|
|
69
|
-
this.#nodeId = options.nodeId;
|
|
70
|
-
this.#supervisor = new RuntimeDeliverySupervisor(this.#ports, this.#nodeId);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Adds one owner-specific delivery runtime.
|
|
74
|
-
* @param runtime Supplies the runtime to configure.
|
|
75
|
-
*/
|
|
76
|
-
add(runtime) {
|
|
77
|
-
if (this.#workers.has(runtime.owner.key)) {
|
|
78
|
-
throw new Error("Environment delivery owner is already configured.");
|
|
79
|
-
}
|
|
80
|
-
const worker = this.#createWorker(runtime, this.#ports, this.#nodeId);
|
|
81
|
-
this.#workers.set(runtime.owner.key, worker);
|
|
82
|
-
try {
|
|
83
|
-
this.#supervisor.add(runtime);
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
this.#workers.delete(runtime.owner.key);
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
89
|
-
void this.#supervisor.start();
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Starts selected shards for one owner-specific obligation.
|
|
93
|
-
*
|
|
94
|
-
* @param obligation Supplies the finite delivery obligation.
|
|
95
|
-
* @param shards Selects shards to run.
|
|
96
|
-
* @returns Evidence produced by the worker.
|
|
97
|
-
*/
|
|
98
|
-
start(obligation, shards) {
|
|
99
|
-
const owner = EnvironmentDeliveryValues.soleOwner(obligation.scopes);
|
|
100
|
-
const worker = this.#workers.get(owner.key);
|
|
101
|
-
if (worker === undefined) {
|
|
102
|
-
return Promise.reject(new Error("Environment delivery owner is not configured."));
|
|
103
|
-
}
|
|
104
|
-
return worker.start(obligation, shards).then(async (evidence) => {
|
|
105
|
-
await this.#supervisor.start();
|
|
106
|
-
return evidence;
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Notifies a running supervisor about new work.
|
|
111
|
-
* @param scope Identifies the changed scope.
|
|
112
|
-
*/
|
|
113
|
-
notify(scope) {
|
|
114
|
-
this.#requiredWorker(scope.owner.key);
|
|
115
|
-
this.#supervisor.notify(scope.owner.key, scope.ready.shard);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Stops every configured owner and aggregates failures.
|
|
119
|
-
*/
|
|
120
|
-
stop() {
|
|
121
|
-
const failures = [];
|
|
122
|
-
for (const [key, worker] of this.#workers) {
|
|
123
|
-
if (this.#stoppedOwners.has(key)) {
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
this.#stopOwner(key, worker, failures);
|
|
127
|
-
}
|
|
128
|
-
try {
|
|
129
|
-
this.#supervisor.stop();
|
|
130
|
-
}
|
|
131
|
-
catch (error) {
|
|
132
|
-
failures.push(error);
|
|
133
|
-
}
|
|
134
|
-
EnvironmentDeliveryValues.throwFailures(failures, "Environment delivery worker stop failed.");
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Awaits every configured worker and supervisor.
|
|
138
|
-
*
|
|
139
|
-
* @returns A promise that resolves after all configured work settles.
|
|
140
|
-
*/
|
|
141
|
-
async awaitSettled() {
|
|
142
|
-
await Promise.all([
|
|
143
|
-
...Array.from(this.#workers.values(), (worker) => worker.awaitSettled()),
|
|
144
|
-
this.#supervisor.awaitSettled(),
|
|
145
|
-
]);
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Closes every configured worker and supervisor.
|
|
149
|
-
*
|
|
150
|
-
* @returns A promise that settles after all configured resources retire.
|
|
151
|
-
*/
|
|
152
|
-
async retire() {
|
|
153
|
-
const settled = await Promise.allSettled([
|
|
154
|
-
...Array.from(this.#workers.values(), (worker) => EnvironmentDeliveryValues.attempt(() => worker.retire())),
|
|
155
|
-
EnvironmentDeliveryValues.attempt(() => this.#supervisor.retire()),
|
|
156
|
-
]);
|
|
157
|
-
const failures = [];
|
|
158
|
-
for (const result of settled) {
|
|
159
|
-
if (result.status === "rejected") {
|
|
160
|
-
failures.push(result.reason);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
EnvironmentDeliveryValues.throwFailures(failures, "Environment delivery worker retirement failed.");
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Stops selected owners and aggregates failures.
|
|
167
|
-
* @param ownerKeys Identifies owners to stop.
|
|
168
|
-
*/
|
|
169
|
-
stopOwners(ownerKeys) {
|
|
170
|
-
const selected = ownerKeys.map((key) => {
|
|
171
|
-
const worker = this.#workers.get(key);
|
|
172
|
-
if (worker === undefined) {
|
|
173
|
-
throw new Error("Environment delivery owner is not configured.");
|
|
174
|
-
}
|
|
175
|
-
return { key, worker };
|
|
176
|
-
});
|
|
177
|
-
const failures = [];
|
|
178
|
-
this.#supervisor.fenceOwners(ownerKeys);
|
|
179
|
-
for (const { key, worker } of selected) {
|
|
180
|
-
if (this.#stoppedOwners.has(key)) {
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
this.#stopOwner(key, worker, failures);
|
|
184
|
-
}
|
|
185
|
-
EnvironmentDeliveryValues.throwFailures(failures, "Environment registration worker stop failed.");
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Awaits selected owners.
|
|
189
|
-
*
|
|
190
|
-
* @param ownerKeys Identifies owners to await.
|
|
191
|
-
* @returns A promise that resolves after selected owner work settles.
|
|
192
|
-
*/
|
|
193
|
-
async awaitOwnersSettled(ownerKeys) {
|
|
194
|
-
await Promise.all([
|
|
195
|
-
...ownerKeys.map((key) => this.#requiredWorker(key).awaitSettled()),
|
|
196
|
-
this.#supervisor.awaitOwnersSettled(ownerKeys),
|
|
197
|
-
]);
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Closes selected owners and releases local state.
|
|
201
|
-
*
|
|
202
|
-
* @param ownerKeys Identifies owners to retire.
|
|
203
|
-
* @returns A promise that settles after selected owners retire.
|
|
204
|
-
*/
|
|
205
|
-
async retireOwners(ownerKeys) {
|
|
206
|
-
const selected = ownerKeys.map((key) => ({ key, worker: this.#requiredWorker(key) }));
|
|
207
|
-
const retired = await Promise.allSettled(selected.map(({ worker }) => EnvironmentDeliveryValues.attempt(() => worker.retire())));
|
|
208
|
-
await this.#supervisor.retireOwners(ownerKeys);
|
|
209
|
-
for (const { key } of selected) {
|
|
210
|
-
this.#workers.delete(key);
|
|
211
|
-
this.#stoppedWorkers.delete(key);
|
|
212
|
-
this.#stoppedSupervisors.delete(key);
|
|
213
|
-
this.#stoppedOwners.delete(key);
|
|
214
|
-
}
|
|
215
|
-
const failures = retired.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
216
|
-
EnvironmentDeliveryValues.throwFailures(failures, "Environment registration worker retirement failed.");
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Finds the configured worker for an owner key.
|
|
220
|
-
*
|
|
221
|
-
* @param key The worker or group key.
|
|
222
|
-
* @returns The result of this delivery operation.
|
|
223
|
-
*/
|
|
224
|
-
#requiredWorker(key) {
|
|
225
|
-
const worker = this.#workers.get(key);
|
|
226
|
-
if (worker === undefined) {
|
|
227
|
-
throw new Error("Environment delivery owner is not configured.");
|
|
228
|
-
}
|
|
229
|
-
return worker;
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Stops one configured owner worker and collects failures.
|
|
233
|
-
*
|
|
234
|
-
* @param key The worker or group key.
|
|
235
|
-
* @param worker The runtime delivery worker.
|
|
236
|
-
* @param failures The failures to propagate.
|
|
237
|
-
*/
|
|
238
|
-
#stopOwner(key, worker, failures) {
|
|
239
|
-
if (!this.#stoppedWorkers.has(key)) {
|
|
240
|
-
try {
|
|
241
|
-
worker.stop();
|
|
242
|
-
this.#stoppedWorkers.add(key);
|
|
243
|
-
}
|
|
244
|
-
catch (error) {
|
|
245
|
-
failures.push(error);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
if (!this.#stoppedSupervisors.has(key)) {
|
|
249
|
-
this.#stoppedSupervisors.add(key);
|
|
250
|
-
}
|
|
251
|
-
if (this.#stoppedWorkers.has(key) && this.#stoppedSupervisors.has(key)) {
|
|
252
|
-
this.#stoppedOwners.add(key);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Coordinates supervisor groups for one environment generation.
|
|
258
|
-
*/
|
|
259
|
-
class RuntimeDeliverySupervisor {
|
|
260
|
-
#groups = new Map();
|
|
261
|
-
#ports;
|
|
262
|
-
#nodeId;
|
|
263
|
-
/**
|
|
264
|
-
* Creates the delivery component with its configured dependencies.
|
|
265
|
-
*
|
|
266
|
-
* @param ports The optional delivery ports.
|
|
267
|
-
* @param nodeId The worker node identity.
|
|
268
|
-
*/
|
|
269
|
-
constructor(ports, nodeId) {
|
|
270
|
-
this.#ports = ports;
|
|
271
|
-
this.#nodeId = nodeId;
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Adds the configured delivery runtime or shards.
|
|
275
|
-
*
|
|
276
|
-
* @param runtime The configured context delivery runtime.
|
|
277
|
-
*/
|
|
278
|
-
add(runtime) {
|
|
279
|
-
const grouped = new Map();
|
|
280
|
-
for (const shard of EnvironmentDeliveryValues.uniqueShards(runtime.scopes)) {
|
|
281
|
-
const shards = grouped.get(shard.ofTotal) ?? [];
|
|
282
|
-
shards.push(shard);
|
|
283
|
-
grouped.set(shard.ofTotal, shards);
|
|
284
|
-
}
|
|
285
|
-
if (grouped.size === 0) {
|
|
286
|
-
throw new Error("Environment delivery supervisor requires at least one shard.");
|
|
287
|
-
}
|
|
288
|
-
for (const [shardCount, shards] of grouped) {
|
|
289
|
-
const key = this.#groupKey(runtime.owner.key, shardCount);
|
|
290
|
-
let group = this.#groups.get(key);
|
|
291
|
-
if (group === undefined) {
|
|
292
|
-
group = EnvironmentDeliveryValues.createSupervisorGroup(runtime, shards, this.#ports, this.#nodeId);
|
|
293
|
-
this.#groups.set(key, group);
|
|
294
|
-
}
|
|
295
|
-
group.add(runtime.owner.key, runtime, shards);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Removes an owner route from this runtime.
|
|
300
|
-
*
|
|
301
|
-
* @param ownerKey The configured owner key.
|
|
302
|
-
*/
|
|
303
|
-
remove(ownerKey) {
|
|
304
|
-
for (const group of this.#groups.values())
|
|
305
|
-
group.remove(ownerKey);
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Starts the configured delivery worker or supervisor.
|
|
309
|
-
*
|
|
310
|
-
* @returns The result of this delivery operation.
|
|
311
|
-
*/
|
|
312
|
-
async start() {
|
|
313
|
-
if (!managedDeliveryActivated) {
|
|
314
|
-
waitingManagedSupervisors.add(() => {
|
|
315
|
-
void this.start();
|
|
316
|
-
});
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
if (cancelManagedDelivery)
|
|
320
|
-
return;
|
|
321
|
-
await Promise.all(Array.from(this.#groups.values(), (group) => group.start()));
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Notifies the selected delivery scope or shard.
|
|
325
|
-
*
|
|
326
|
-
* @param ownerKey The configured owner key.
|
|
327
|
-
* @param shard The shard to process.
|
|
328
|
-
*/
|
|
329
|
-
notify(ownerKey, shard) {
|
|
330
|
-
this.#groups.get(this.#groupKey(ownerKey, shard.ofTotal))?.notify(shard);
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Marks the selected owners as unavailable for new route admission.
|
|
334
|
-
*
|
|
335
|
-
* @param ownerKeys The owner keys in this generation.
|
|
336
|
-
*/
|
|
337
|
-
fenceOwners(ownerKeys) {
|
|
338
|
-
for (const group of this.#groups.values())
|
|
339
|
-
group.fenceOwners(ownerKeys);
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Waits for admitted work for the selected owners to settle.
|
|
343
|
-
*
|
|
344
|
-
* @param ownerKeys The owner keys in this generation.
|
|
345
|
-
* @returns The result of this delivery operation.
|
|
346
|
-
*/
|
|
347
|
-
async awaitOwnersSettled(ownerKeys) {
|
|
348
|
-
await Promise.all(Array.from(this.#groups.values(), (group) => group.awaitOwnersSettled(ownerKeys)));
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Closes the selected owners after admitted work settles.
|
|
352
|
-
*
|
|
353
|
-
* @param ownerKeys The owner keys in this generation.
|
|
354
|
-
* @returns The result of this delivery operation.
|
|
355
|
-
*/
|
|
356
|
-
async retireOwners(ownerKeys) {
|
|
357
|
-
for (const [key, group] of this.#groups) {
|
|
358
|
-
await group.retireOwners(ownerKeys);
|
|
359
|
-
if (group.empty)
|
|
360
|
-
this.#groups.delete(key);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Stops admission and starts delivery shutdown.
|
|
365
|
-
*/
|
|
366
|
-
stop() {
|
|
367
|
-
const failures = [];
|
|
368
|
-
for (const group of this.#groups.values()) {
|
|
369
|
-
try {
|
|
370
|
-
group.stop();
|
|
371
|
-
}
|
|
372
|
-
catch (error) {
|
|
373
|
-
failures.push(error);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
EnvironmentDeliveryValues.throwFailures(failures, "Environment delivery supervisor stop failed.");
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Waits for the active delivery work to settle.
|
|
380
|
-
*
|
|
381
|
-
* @returns The result of this delivery operation.
|
|
382
|
-
*/
|
|
383
|
-
async awaitSettled() {
|
|
384
|
-
const settled = await Promise.allSettled(Array.from(this.#groups.values(), (group) => group.awaitSettled()));
|
|
385
|
-
EnvironmentDeliveryValues.throwFailures(settled.flatMap((result) => (result.status === "rejected" ? [result.reason] : [])), "Environment delivery supervisor settlement failed.");
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Closes this delivery worker after settling its work.
|
|
389
|
-
*
|
|
390
|
-
* @returns The result of this delivery operation.
|
|
391
|
-
*/
|
|
392
|
-
async retire() {
|
|
393
|
-
const settled = await Promise.allSettled(Array.from(this.#groups.values(), (group) => EnvironmentDeliveryValues.attempt(() => group.retire())));
|
|
394
|
-
EnvironmentDeliveryValues.throwFailures(settled.flatMap((result) => (result.status === "rejected" ? [result.reason] : [])), "Environment delivery supervisor retirement failed.");
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Builds a stable supervisor-group key for one owner and shard total.
|
|
398
|
-
*
|
|
399
|
-
* @param ownerKey The configured owner key.
|
|
400
|
-
* @param shardCount The shard total for this supervisor group.
|
|
401
|
-
* @returns The result of this delivery operation.
|
|
402
|
-
*/
|
|
403
|
-
#groupKey(ownerKey, shardCount) {
|
|
404
|
-
return this.#ports?.source === undefined
|
|
405
|
-
? `${ownerKey}/${String(shardCount)}`
|
|
406
|
-
: `remote/${String(shardCount)}`;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* Keeps admitted routes stable while one shard supervisor drains.
|
|
411
|
-
*/
|
|
412
|
-
class RuntimeDeliverySupervisorGroup {
|
|
413
|
-
#source;
|
|
414
|
-
#supervisor;
|
|
415
|
-
#routes = new Map();
|
|
416
|
-
#retiringOwners = new Set();
|
|
417
|
-
#active = new Map();
|
|
418
|
-
#reserved;
|
|
419
|
-
shardCount;
|
|
420
|
-
#start;
|
|
421
|
-
#stopped = false;
|
|
422
|
-
#close;
|
|
423
|
-
/**
|
|
424
|
-
* Creates the delivery component with its configured dependencies.
|
|
425
|
-
*
|
|
426
|
-
* @param options The delivery or cancellation options.
|
|
427
|
-
*/
|
|
428
|
-
constructor(options) {
|
|
429
|
-
// `createSupervisorGroup()` rejects an empty shard collection before internal construction.
|
|
430
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
431
|
-
const first = options.shards[0];
|
|
432
|
-
this.shardCount = first.ofTotal;
|
|
433
|
-
this.#reserved = new Map(options.shards.map((shard) => [shard.key(), new Map()]));
|
|
434
|
-
this.#source =
|
|
435
|
-
options.source === undefined
|
|
436
|
-
? new LocalDeliverySource(options.shards)
|
|
437
|
-
: EnvironmentDeliveryValues.requireSource(options.source);
|
|
438
|
-
this.#supervisor = new DeliverySupervisor({
|
|
439
|
-
source: this.#source,
|
|
440
|
-
delivery: options.delivery,
|
|
441
|
-
onMessage: (message) => this.#route(message),
|
|
442
|
-
});
|
|
443
|
-
deliverySupervisorAccess.installAdmission(this.#supervisor, (message) => this.#accept(message));
|
|
444
|
-
deliverySupervisorAccess.installMessageSettled(this.#supervisor, (message) => {
|
|
445
|
-
this.#settleReservation(message);
|
|
446
|
-
});
|
|
447
|
-
deliverySupervisorAccess.installFinalization(this.#supervisor, (shard) => {
|
|
448
|
-
this.#releaseUndeliveredReservations(shard);
|
|
449
|
-
});
|
|
450
|
-
if (options.logger !== undefined) {
|
|
451
|
-
deliverySupervisorAccess.installLogger(this.#supervisor, options.logger);
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Adds the configured delivery runtime or shards.
|
|
456
|
-
*
|
|
457
|
-
* @param ownerKey The configured owner key.
|
|
458
|
-
* @param runtime The configured context delivery runtime.
|
|
459
|
-
* @param shards The shards assigned to this runtime.
|
|
460
|
-
*/
|
|
461
|
-
add(ownerKey, runtime, shards) {
|
|
462
|
-
if (this.#source instanceof LocalDeliverySource)
|
|
463
|
-
this.#source.add(shards);
|
|
464
|
-
for (const scope of runtime.scopes) {
|
|
465
|
-
if (scope.ready.shard.ofTotal !== this.shardCount)
|
|
466
|
-
continue;
|
|
467
|
-
const key = _a.key(scope.ready);
|
|
468
|
-
const routes = this.#routes.get(key) ?? [];
|
|
469
|
-
routes.push({
|
|
470
|
-
ownerKey,
|
|
471
|
-
descriptor: runtime.descriptor,
|
|
472
|
-
tenant: runtime.tenant,
|
|
473
|
-
tenantKey: runtime.tenant.tenantId === undefined
|
|
474
|
-
? undefined
|
|
475
|
-
: String(TenantBoundary.from(runtime.tenant.tenantId).key),
|
|
476
|
-
});
|
|
477
|
-
this.#routes.set(key, routes);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
/**
|
|
481
|
-
* Checks whether this supervisor group has configured routes.
|
|
482
|
-
*
|
|
483
|
-
* @returns The result of this delivery operation.
|
|
484
|
-
*/
|
|
485
|
-
get empty() {
|
|
486
|
-
return this.#routes.size === 0;
|
|
487
|
-
}
|
|
488
|
-
/**
|
|
489
|
-
* Marks the selected owners as unavailable for new route admission.
|
|
490
|
-
*
|
|
491
|
-
* @param ownerKeys The owner keys in this generation.
|
|
492
|
-
*/
|
|
493
|
-
fenceOwners(ownerKeys) {
|
|
494
|
-
for (const ownerKey of ownerKeys)
|
|
495
|
-
this.#retiringOwners.add(ownerKey);
|
|
496
|
-
}
|
|
497
|
-
/**
|
|
498
|
-
* Waits for admitted work for the selected owners to settle.
|
|
499
|
-
*
|
|
500
|
-
* @param ownerKeys The owner keys in this generation.
|
|
501
|
-
* @returns The result of this delivery operation.
|
|
502
|
-
*/
|
|
503
|
-
async awaitOwnersSettled(ownerKeys) {
|
|
504
|
-
await Promise.all(Array.from(this.#reserved.values(), async (reservations) => Promise.all(Array.from(reservations.values())
|
|
505
|
-
.filter((reservation) => ownerKeys.includes(reservation.route.ownerKey))
|
|
506
|
-
.map((reservation) => reservation.settled.promise))));
|
|
507
|
-
await Promise.all(ownerKeys.map(async (ownerKey) => {
|
|
508
|
-
const active = this.#active.get(ownerKey);
|
|
509
|
-
if (active !== undefined)
|
|
510
|
-
await Promise.allSettled(active);
|
|
511
|
-
}));
|
|
512
|
-
}
|
|
513
|
-
/**
|
|
514
|
-
* Closes the selected owners after admitted work settles.
|
|
515
|
-
*
|
|
516
|
-
* @param ownerKeys The owner keys in this generation.
|
|
517
|
-
* @returns The result of this delivery operation.
|
|
518
|
-
*/
|
|
519
|
-
async retireOwners(ownerKeys) {
|
|
520
|
-
this.fenceOwners(ownerKeys);
|
|
521
|
-
await this.awaitOwnersSettled(ownerKeys);
|
|
522
|
-
for (const ownerKey of ownerKeys)
|
|
523
|
-
this.remove(ownerKey);
|
|
524
|
-
if (this.empty)
|
|
525
|
-
await this.retire();
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Removes an owner route from this runtime.
|
|
529
|
-
*
|
|
530
|
-
* @param ownerKey The configured owner key.
|
|
531
|
-
*/
|
|
532
|
-
remove(ownerKey) {
|
|
533
|
-
for (const [key, routes] of this.#routes) {
|
|
534
|
-
const retained = routes.filter((route) => route.ownerKey !== ownerKey);
|
|
535
|
-
if (retained.length === 0)
|
|
536
|
-
this.#routes.delete(key);
|
|
537
|
-
else
|
|
538
|
-
this.#routes.set(key, retained);
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
/**
|
|
542
|
-
* Starts the configured delivery worker or supervisor.
|
|
543
|
-
*
|
|
544
|
-
* @returns The result of this delivery operation.
|
|
545
|
-
*/
|
|
546
|
-
start() {
|
|
547
|
-
if (this.#stopped) {
|
|
548
|
-
return Promise.reject(new Error("Environment delivery supervisor is stopped."));
|
|
549
|
-
}
|
|
550
|
-
if (this.#start === undefined) {
|
|
551
|
-
this.#start = this.#supervisor.start().then(() => {
|
|
552
|
-
if (this.#source instanceof LocalDeliverySource)
|
|
553
|
-
this.#source.enableRecovery();
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
return this.#start;
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* Notifies the selected delivery scope or shard.
|
|
560
|
-
*
|
|
561
|
-
* @param shard The shard to process.
|
|
562
|
-
*/
|
|
563
|
-
notify(shard) {
|
|
564
|
-
if (this.#stopped)
|
|
565
|
-
return;
|
|
566
|
-
// spine-log-boundary: server.delivery_notify_start
|
|
567
|
-
void this.start()
|
|
568
|
-
.then(() => {
|
|
569
|
-
this.#supervisor.notify(shard);
|
|
570
|
-
})
|
|
571
|
-
.catch(() => undefined);
|
|
572
|
-
}
|
|
573
|
-
/**
|
|
574
|
-
* Stops admission and starts delivery shutdown.
|
|
575
|
-
*/
|
|
576
|
-
stop() {
|
|
577
|
-
if (this.#stopped)
|
|
578
|
-
return;
|
|
579
|
-
this.#stopped = true;
|
|
580
|
-
this.#close = this.#supervisor.close();
|
|
581
|
-
// spine-log-boundary: server.delivery_supervisor_close
|
|
582
|
-
void this.#close.catch(() => undefined);
|
|
583
|
-
}
|
|
584
|
-
/**
|
|
585
|
-
* Waits for the active delivery work to settle.
|
|
586
|
-
*
|
|
587
|
-
* @returns The result of this delivery operation.
|
|
588
|
-
*/
|
|
589
|
-
async awaitSettled() {
|
|
590
|
-
await this.#start;
|
|
591
|
-
await this.#close;
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
* Closes this delivery worker after settling its work.
|
|
595
|
-
*
|
|
596
|
-
* @returns The result of this delivery operation.
|
|
597
|
-
*/
|
|
598
|
-
async retire() {
|
|
599
|
-
this.stop();
|
|
600
|
-
await this.awaitSettled();
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Accepts an Inbox message and reserves its exact route.
|
|
604
|
-
*
|
|
605
|
-
* @param message The persisted Inbox message.
|
|
606
|
-
* @returns The result of this delivery operation.
|
|
607
|
-
*/
|
|
608
|
-
#accept(message) {
|
|
609
|
-
const route = this.#select(message);
|
|
610
|
-
if (route !== undefined) {
|
|
611
|
-
// `options.shards` initializes one private reservation map per supervised shard.
|
|
612
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
613
|
-
const reservations = this.#reserved.get(message.shard.key());
|
|
614
|
-
const key = _a.messageKey(message);
|
|
615
|
-
if (reservations.has(key))
|
|
616
|
-
return false;
|
|
617
|
-
reservations.set(key, {
|
|
618
|
-
route,
|
|
619
|
-
settled: Promise.withResolvers(),
|
|
620
|
-
});
|
|
621
|
-
}
|
|
622
|
-
return route !== undefined;
|
|
623
|
-
}
|
|
624
|
-
/**
|
|
625
|
-
* Routes an admitted Inbox message to its reserved endpoint.
|
|
626
|
-
*
|
|
627
|
-
* @param message The persisted Inbox message.
|
|
628
|
-
* @returns The result of this delivery operation.
|
|
629
|
-
*/
|
|
630
|
-
#route(message) {
|
|
631
|
-
receptionObservation.markManaged();
|
|
632
|
-
const key = _a.messageKey(message);
|
|
633
|
-
// `Delivery` invokes the callback only after this group's admission reserved its route.
|
|
634
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
635
|
-
const reservations = this.#reserved.get(message.shard.key());
|
|
636
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
637
|
-
const reservation = reservations.get(key);
|
|
638
|
-
const route = reservation.route;
|
|
639
|
-
const active = this.#active.get(route.ownerKey) ?? new Set();
|
|
640
|
-
this.#active.set(route.ownerKey, active);
|
|
641
|
-
const replay = Promise.resolve()
|
|
642
|
-
.then(() => route.descriptor.replay(message, route.tenant.tenantId))
|
|
643
|
-
.finally(() => {
|
|
644
|
-
active.delete(replay);
|
|
645
|
-
if (active.size === 0)
|
|
646
|
-
this.#active.delete(route.ownerKey);
|
|
647
|
-
});
|
|
648
|
-
active.add(replay);
|
|
649
|
-
return replay;
|
|
650
|
-
}
|
|
651
|
-
/**
|
|
652
|
-
* Resolves and removes one reservation after its complete processing action.
|
|
653
|
-
*
|
|
654
|
-
* @param message The settled Inbox message.
|
|
655
|
-
*/
|
|
656
|
-
#settleReservation(message) {
|
|
657
|
-
// The constructor initializes a reservation map for every supervised shard.
|
|
658
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
659
|
-
const reservations = this.#reserved.get(message.shard.key());
|
|
660
|
-
const key = _a.messageKey(message);
|
|
661
|
-
const reservation = reservations.get(key);
|
|
662
|
-
if (reservation === undefined)
|
|
663
|
-
return;
|
|
664
|
-
reservations.delete(key);
|
|
665
|
-
reservation.settled.resolve(undefined);
|
|
666
|
-
}
|
|
667
|
-
/**
|
|
668
|
-
* Clears route reservations when a shard run finishes.
|
|
669
|
-
*
|
|
670
|
-
* @param shard The shard to process.
|
|
671
|
-
*/
|
|
672
|
-
#releaseUndeliveredReservations(shard) {
|
|
673
|
-
// `options.shards` initializes one private reservation map per supervised shard.
|
|
674
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
675
|
-
const reservations = this.#reserved.get(shard.key());
|
|
676
|
-
for (const reservation of reservations.values()) {
|
|
677
|
-
reservation.settled.resolve(undefined);
|
|
678
|
-
}
|
|
679
|
-
reservations.clear();
|
|
680
|
-
}
|
|
681
|
-
/**
|
|
682
|
-
* Finds the configured route for an Inbox message.
|
|
683
|
-
*
|
|
684
|
-
* @param message The persisted Inbox message.
|
|
685
|
-
* @returns The result of this delivery operation.
|
|
686
|
-
*/
|
|
687
|
-
#select(message) {
|
|
688
|
-
const key = _a.key(message);
|
|
689
|
-
const routes = this.#routes.get(key);
|
|
690
|
-
const route = _a.select(routes, message);
|
|
691
|
-
return route === undefined || this.#retiringOwners.has(route.ownerKey) ? undefined : route;
|
|
692
|
-
}
|
|
693
|
-
/**
|
|
694
|
-
* Finds the matching route for an Inbox message.
|
|
695
|
-
*
|
|
696
|
-
* @param routes The candidate routes.
|
|
697
|
-
* @param message The persisted Inbox message.
|
|
698
|
-
* @returns The result of this delivery operation.
|
|
699
|
-
*/
|
|
700
|
-
static select(routes, message) {
|
|
701
|
-
if (routes === undefined || routes.length === 0)
|
|
702
|
-
return undefined;
|
|
703
|
-
const tenantKey = _a.tenantKey(message);
|
|
704
|
-
return routes.find((route) => route.tenantKey === tenantKey);
|
|
705
|
-
}
|
|
706
|
-
/**
|
|
707
|
-
*
|
|
708
|
-
* Finds the tenant boundary key from the delivery label's matching envelope.
|
|
709
|
-
* `HANDLE_COMMAND` reads the Command actor tenant; Event labels read imported
|
|
710
|
-
* or past-message Event origin tenants.
|
|
711
|
-
*
|
|
712
|
-
* @param message Contains the admitted delivery message.
|
|
713
|
-
* @returns The tenant boundary key when the supported envelope carries one.
|
|
714
|
-
*/
|
|
715
|
-
static tenantKey(message) {
|
|
716
|
-
if (message.signal === undefined)
|
|
717
|
-
return undefined;
|
|
718
|
-
try {
|
|
719
|
-
if (message.label === "HANDLE_COMMAND") {
|
|
720
|
-
const tenantId = fromBinary(CommandSchema, message.signal.value).context?.actorContext
|
|
721
|
-
?.tenantId;
|
|
722
|
-
return tenantId === undefined ? undefined : String(TenantBoundary.from(tenantId).key);
|
|
723
|
-
}
|
|
724
|
-
const origin = fromBinary(EventSchema, message.signal.value).context?.origin;
|
|
725
|
-
if (origin?.case === "importContext") {
|
|
726
|
-
const value = origin.value.tenantId;
|
|
727
|
-
return value === undefined ? undefined : String(TenantBoundary.from(value).key);
|
|
728
|
-
}
|
|
729
|
-
if (origin?.case === "pastMessage") {
|
|
730
|
-
const value = origin.value.actorContext?.tenantId;
|
|
731
|
-
return value === undefined ? undefined : String(TenantBoundary.from(value).key);
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
catch {
|
|
735
|
-
return undefined;
|
|
736
|
-
}
|
|
737
|
-
return undefined;
|
|
738
|
-
}
|
|
739
|
-
/**
|
|
740
|
-
* Builds a route key for one configured endpoint.
|
|
741
|
-
*
|
|
742
|
-
* @param route The configured route.
|
|
743
|
-
* @returns The result of this delivery operation.
|
|
744
|
-
*/
|
|
745
|
-
static key(route) {
|
|
746
|
-
const targetTypeUrl = route.inboxId?.targetTypeUrl ?? route.targetTypeUrl;
|
|
747
|
-
if (targetTypeUrl === undefined)
|
|
748
|
-
throw new Error("Environment delivery route has no target type.");
|
|
749
|
-
return JSON.stringify([route.label, targetTypeUrl, route.shard.index, route.shard.ofTotal]);
|
|
750
|
-
}
|
|
751
|
-
/**
|
|
752
|
-
* Builds an exact route-reservation key for one Inbox message.
|
|
753
|
-
*
|
|
754
|
-
* @param message The persisted Inbox message.
|
|
755
|
-
* @returns The result of this delivery operation.
|
|
756
|
-
*/
|
|
757
|
-
static messageKey(message) {
|
|
758
|
-
return `${message.id.shard.key()}/${message.id.value}`;
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
_a = RuntimeDeliverySupervisorGroup;
|
|
762
|
-
/**
|
|
763
|
-
* Supplies local shard recovery observations to the supervisor.
|
|
764
|
-
*/
|
|
765
|
-
class LocalDeliverySource {
|
|
766
|
-
#shards = new Map();
|
|
767
|
-
#recoveryEnabled = false;
|
|
768
|
-
/**
|
|
769
|
-
* Creates the delivery component with its configured dependencies.
|
|
770
|
-
*
|
|
771
|
-
* @param shards The shards assigned to this runtime.
|
|
772
|
-
*/
|
|
773
|
-
constructor(shards) {
|
|
774
|
-
this.add(shards);
|
|
775
|
-
}
|
|
776
|
-
/**
|
|
777
|
-
* Adds the configured delivery runtime or shards.
|
|
778
|
-
*
|
|
779
|
-
* @param shards The shards assigned to this runtime.
|
|
780
|
-
*/
|
|
781
|
-
add(shards) {
|
|
782
|
-
for (const shard of shards)
|
|
783
|
-
this.#shards.set(shard.key(), shard);
|
|
784
|
-
}
|
|
785
|
-
/**
|
|
786
|
-
* Sets local shards as eligible for periodic recovery.
|
|
787
|
-
*/
|
|
788
|
-
enableRecovery() {
|
|
789
|
-
this.#recoveryEnabled = true;
|
|
790
|
-
}
|
|
791
|
-
/**
|
|
792
|
-
* Returns the locally recoverable shard snapshot.
|
|
793
|
-
*
|
|
794
|
-
* @returns The result of this delivery operation.
|
|
795
|
-
*/
|
|
796
|
-
shardSnapshot() {
|
|
797
|
-
return Promise.resolve(this.#recoveryEnabled
|
|
798
|
-
? Array.from(this.#shards.values(), (shard) => ({
|
|
799
|
-
shard,
|
|
800
|
-
status: "NOT_PICKED",
|
|
801
|
-
messages: 1,
|
|
802
|
-
}))
|
|
803
|
-
: []);
|
|
804
|
-
}
|
|
805
|
-
/**
|
|
806
|
-
* Observes shard changes until the operation is cancelled.
|
|
807
|
-
*
|
|
808
|
-
* @param options The delivery or cancellation options.
|
|
809
|
-
* @returns The result of this delivery operation.
|
|
810
|
-
*/
|
|
811
|
-
observeShardUpdates(options) {
|
|
812
|
-
return EnvironmentDeliveryValues.updatesUntilAborted(options?.signal);
|
|
813
|
-
}
|
|
814
|
-
/**
|
|
815
|
-
* Returns expired local ownership records.
|
|
816
|
-
*
|
|
817
|
-
* @returns The result of this delivery operation.
|
|
818
|
-
*/
|
|
819
|
-
releaseExpired() {
|
|
820
|
-
return Promise.resolve([]);
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
/**
|
|
824
|
-
* Groups private delivery-runtime assembly and failure operations.
|
|
825
|
-
*
|
|
826
|
-
* @internal
|
|
827
|
-
*/
|
|
828
|
-
const EnvironmentDeliveryValues = Object.freeze({
|
|
829
|
-
/**
|
|
830
|
-
* Validates a delivery source before use.
|
|
831
|
-
*
|
|
832
|
-
* @param source The source to validate.
|
|
833
|
-
* @returns The validated delivery source.
|
|
834
|
-
*/
|
|
835
|
-
requireSource(source) {
|
|
836
|
-
if (source === null ||
|
|
837
|
-
typeof source !== "object" ||
|
|
838
|
-
typeof source.shardSnapshot !== "function" ||
|
|
839
|
-
typeof source.observeShardUpdates !== "function" ||
|
|
840
|
-
typeof source.releaseExpired !== "function") {
|
|
841
|
-
throw new TypeError("Environment delivery source is invalid.");
|
|
842
|
-
}
|
|
843
|
-
return source;
|
|
844
|
-
},
|
|
845
|
-
/**
|
|
846
|
-
* Creates the worker that drains one context runtime.
|
|
847
|
-
*
|
|
848
|
-
* @param runtime The context runtime to serve.
|
|
849
|
-
* @param ports Optional delivery ports.
|
|
850
|
-
* @param nodeId Optional node identity.
|
|
851
|
-
* @returns The configured worker.
|
|
852
|
-
*/
|
|
853
|
-
createWorker(runtime, ports, nodeId) {
|
|
854
|
-
const delivery = new Delivery({
|
|
855
|
-
context: runtime.context,
|
|
856
|
-
storageFactory: runtime.storageFactory,
|
|
857
|
-
node: nodeId ?? runtime.context.name,
|
|
858
|
-
...(ports ?? {}),
|
|
859
|
-
});
|
|
860
|
-
const worker = new DeliveryWorker({
|
|
861
|
-
delivery,
|
|
862
|
-
shards: EnvironmentDeliveryValues.uniqueShards(runtime.scopes),
|
|
863
|
-
onMessage: (message) => runtime.descriptor.replay(message, runtime.tenant.tenantId),
|
|
864
|
-
});
|
|
865
|
-
return deliveryRunWorkers.worker(worker);
|
|
866
|
-
},
|
|
867
|
-
/**
|
|
868
|
-
* Creates a supervisor group for shards with one total.
|
|
869
|
-
*
|
|
870
|
-
* @param runtime The context runtime to serve.
|
|
871
|
-
* @param shards The assigned shards.
|
|
872
|
-
* @param ports Optional delivery ports.
|
|
873
|
-
* @param nodeId Optional node identity.
|
|
874
|
-
* @returns The configured supervisor group.
|
|
875
|
-
*/
|
|
876
|
-
createSupervisorGroup(runtime, shards, ports, nodeId) {
|
|
877
|
-
const first = shards[0];
|
|
878
|
-
if (first === undefined) {
|
|
879
|
-
throw new Error("Environment delivery supervisor requires at least one shard.");
|
|
880
|
-
}
|
|
881
|
-
const builder = new DeliveryBuilder()
|
|
882
|
-
.withContext(runtime.context)
|
|
883
|
-
.withStorageFactory(runtime.storageFactory)
|
|
884
|
-
.withStrategy(UniformAcrossAllShards.forNumber(first.ofTotal))
|
|
885
|
-
.withNode(nodeId ?? runtime.context.name);
|
|
886
|
-
if (ports !== undefined)
|
|
887
|
-
builder.withInbox(ports.inbox).withWorkRegistry(ports.workRegistry);
|
|
888
|
-
return new RuntimeDeliverySupervisorGroup({
|
|
889
|
-
delivery: builder.build(),
|
|
890
|
-
shards,
|
|
891
|
-
...(ports?.source === undefined ? {} : { source: ports.source }),
|
|
892
|
-
...(runtime.logger === undefined ? {} : { logger: runtime.logger }),
|
|
893
|
-
});
|
|
894
|
-
},
|
|
895
|
-
/**
|
|
896
|
-
* Creates an update stream that finishes on cancellation.
|
|
897
|
-
*
|
|
898
|
-
* @param signal The optional cancellation signal.
|
|
899
|
-
* @returns The cancellation-aware stream.
|
|
900
|
-
*/
|
|
901
|
-
updatesUntilAborted(signal) {
|
|
902
|
-
return {
|
|
903
|
-
/**
|
|
904
|
-
* Returns the cancellation-aware update iterator.
|
|
905
|
-
*
|
|
906
|
-
* @returns The result of this delivery operation.
|
|
907
|
-
*/
|
|
908
|
-
[Symbol.asyncIterator]() {
|
|
909
|
-
return {
|
|
910
|
-
next: () => new Promise((resolve) => {
|
|
911
|
-
if (signal?.aborted) {
|
|
912
|
-
resolve({ done: true, value: undefined });
|
|
913
|
-
return;
|
|
914
|
-
}
|
|
915
|
-
signal?.addEventListener("abort", () => {
|
|
916
|
-
resolve({ done: true, value: undefined });
|
|
917
|
-
}, { once: true });
|
|
918
|
-
}),
|
|
919
|
-
};
|
|
920
|
-
},
|
|
921
|
-
};
|
|
922
|
-
},
|
|
923
|
-
/**
|
|
924
|
-
* Finds the sole owner shared by the supplied scopes.
|
|
925
|
-
*
|
|
926
|
-
* @param scopes The exact delivery scopes.
|
|
927
|
-
* @returns Their shared owner.
|
|
928
|
-
*/
|
|
929
|
-
soleOwner(scopes) {
|
|
930
|
-
const first = scopes[0]?.owner;
|
|
931
|
-
if (first === undefined || scopes.some(({ owner }) => owner.key !== first.key)) {
|
|
932
|
-
throw new Error("Environment delivery obligation requires exactly one owner.");
|
|
933
|
-
}
|
|
934
|
-
return first;
|
|
935
|
-
},
|
|
936
|
-
/**
|
|
937
|
-
* Collects distinct shards from the supplied scopes.
|
|
938
|
-
*
|
|
939
|
-
* @param scopes The exact delivery scopes.
|
|
940
|
-
* @returns Their distinct shards.
|
|
941
|
-
*/
|
|
942
|
-
uniqueShards(scopes) {
|
|
943
|
-
const shards = new Map();
|
|
944
|
-
for (const { ready } of scopes) {
|
|
945
|
-
shards.set(ready.shard.key(), ready.shard);
|
|
946
|
-
}
|
|
947
|
-
return Object.freeze([...shards.values()]);
|
|
948
|
-
},
|
|
949
|
-
/**
|
|
950
|
-
* Throws collected failures without losing their identity.
|
|
951
|
-
*
|
|
952
|
-
* @param failures The failures to propagate.
|
|
953
|
-
* @param message The aggregate message when several failures occurred.
|
|
954
|
-
*/
|
|
955
|
-
throwFailures(failures, message) {
|
|
956
|
-
if (failures.length === 1) {
|
|
957
|
-
throw failures[0];
|
|
958
|
-
}
|
|
959
|
-
if (failures.length > 1) {
|
|
960
|
-
throw new AggregateError(failures, message);
|
|
961
|
-
}
|
|
962
|
-
},
|
|
963
|
-
/**
|
|
964
|
-
* Awaits one asynchronous cleanup action.
|
|
965
|
-
*
|
|
966
|
-
* @param action The action to await.
|
|
967
|
-
* @returns Completion of that action.
|
|
968
|
-
*/
|
|
969
|
-
async attempt(action) {
|
|
970
|
-
await action();
|
|
971
|
-
},
|
|
972
|
-
});
|
|
973
|
-
//# sourceMappingURL=environment-delivery-worker.js.map
|