@zlink-systems/framework 0.30.1 → 0.30.2
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/.tsbuildinfo +1 -1
- package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
- package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
- package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
- package/dist/contracts/Common/encoded-payload-storage.js +5 -2
- package/dist/contracts/Configuration/Builders.d.ts +1 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
- package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
- package/dist/contracts/Locations/Rows.d.ts +2 -0
- package/dist/contracts/Spots/Contracts.d.ts +4 -0
- package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
- package/dist/runtime/abort.d.ts +5 -0
- package/dist/runtime/abort.js +10 -0
- package/dist/runtime/actors/actor-authority-publication.js +3 -2
- package/dist/runtime/actors/actor-client.d.ts +0 -1
- package/dist/runtime/actors/actor-client.js +38 -45
- package/dist/runtime/actors/actor-context.d.ts +2 -0
- package/dist/runtime/actors/actor-context.js +46 -9
- package/dist/runtime/actors/actor-handoff.d.ts +7 -3
- package/dist/runtime/actors/actor-handoff.js +212 -88
- package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
- package/dist/runtime/actors/actor-local-native-join.js +4 -0
- package/dist/runtime/actors/actor-mailbox.js +27 -1
- package/dist/runtime/actors/actor-remote-joiner.js +3 -1
- package/dist/runtime/actors/actor-reply.d.ts +4 -0
- package/dist/runtime/actors/actor-reply.js +29 -0
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
- package/dist/runtime/actors/actor-runtime-state.js +2 -20
- package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
- package/dist/runtime/actors/index.d.ts +6 -2
- package/dist/runtime/actors/index.js +37 -21
- package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
- package/dist/runtime/actors/session-disconnected-wire.js +48 -0
- package/dist/runtime/admission.d.ts +9 -1
- package/dist/runtime/admission.js +55 -32
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
- package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
- package/dist/runtime/application-jobs/contracts.d.ts +2 -0
- package/dist/runtime/backend/contracts/index.d.ts +19 -3
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
- package/dist/runtime/backend/mesh-completion-table.js +5 -0
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
- package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
- package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
- package/dist/runtime/channels/channel-clients.d.ts +1 -0
- package/dist/runtime/channels/channel-clients.js +20 -5
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
- package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
- package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
- package/dist/runtime/channels/channel-dispatchers.js +44 -37
- package/dist/runtime/channels/channel-envelope.d.ts +1 -0
- package/dist/runtime/channels/channel-envelope.js +74 -31
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
- package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
- package/dist/runtime/channels/channel-runtime-manager.js +4 -4
- package/dist/runtime/channels/channel-transports.d.ts +0 -1
- package/dist/runtime/channels/channel-transports.js +35 -33
- package/dist/runtime/channels/client-server-location-runtime.js +5 -4
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/fanout-location-runtime.js +3 -3
- package/dist/runtime/diagnostics/flow-context.js +19 -7
- package/dist/runtime/diagnostics/index.js +4 -9
- package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
- package/dist/runtime/diagnostics/message-flow.js +35 -5
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
- package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
- package/dist/runtime/execution/index.d.ts +4 -2
- package/dist/runtime/execution/index.js +33 -10
- package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
- package/dist/runtime/execution/serial-execution-queue.js +21 -2
- package/dist/runtime/execution/state-lane.d.ts +2 -0
- package/dist/runtime/execution/state-lane.js +5 -0
- package/dist/runtime/foundation/operation-registry.d.ts +25 -1
- package/dist/runtime/foundation/operation-registry.js +86 -18
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
- package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
- package/dist/runtime/foundation/service-liveness-registry.js +38 -0
- package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
- package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
- package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
- package/dist/runtime/foundation/service-stateful-registry.js +24 -26
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
- package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
- package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
- package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
- package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
- package/dist/runtime/host/actor-packet-relay.js +59 -72
- package/dist/runtime/host/actor-placement-coordinator.js +25 -8
- package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
- package/dist/runtime/host/actor-transfer-runtime.js +85 -331
- package/dist/runtime/host/application-job-queue.d.ts +24 -3
- package/dist/runtime/host/application-job-queue.js +28 -41
- package/dist/runtime/host/index.d.ts +5 -1
- package/dist/runtime/host/index.js +171 -97
- package/dist/runtime/host/location-runtime-owner.js +2 -6
- package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
- package/dist/runtime/host/mesh-router-resolver.js +14 -6
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
- package/dist/runtime/host/remote-bound-session-relay.js +71 -190
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
- package/dist/runtime/host/route-mesh-runtime.js +5 -3
- package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
- package/dist/runtime/host/runtime-shutdown.js +3 -2
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
- package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
- package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
- package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
- package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
- package/dist/runtime/locations/auto-connect-loop.js +22 -14
- package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
- package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
- package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
- package/dist/runtime/locations/descriptor-publication.js +11 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
- package/dist/runtime/locations/in-memory-authority-store.js +56 -19
- package/dist/runtime/locations/in-memory-location-store.js +1 -10
- package/dist/runtime/locations/index.d.ts +1 -0
- package/dist/runtime/locations/index.js +1 -0
- package/dist/runtime/locations/lease-tracker.js +1 -6
- package/dist/runtime/locations/location-store-repository.d.ts +51 -1
- package/dist/runtime/locations/location-store-repository.js +363 -139
- package/dist/runtime/locations/relocation-blob.d.ts +18 -1
- package/dist/runtime/locations/relocation-blob.js +52 -1
- package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
- package/dist/runtime/locations/request-source-resolver.js +80 -0
- package/dist/runtime/locations/resolvers.js +1 -1
- package/dist/runtime/locations/runtime.d.ts +6 -2
- package/dist/runtime/locations/runtime.js +37 -30
- package/dist/runtime/messaging/payload-codec.d.ts +7 -1
- package/dist/runtime/messaging/payload-codec.js +7 -6
- package/dist/runtime/messaging/request-result.js +29 -26
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
- package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
- package/dist/runtime/spots/index.d.ts +18 -11
- package/dist/runtime/spots/index.js +234 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +21 -11
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +7 -7
- package/dist/runtime/spots/spot-activation.d.ts +6 -3
- package/dist/runtime/spots/spot-activation.js +123 -44
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
- package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-membership.js +0 -8
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
- package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
- package/dist/runtime/spots/spot-entry-activation.js +14 -9
- package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
- package/dist/runtime/spots/spot-handler-registry.js +6 -2
- package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
- package/dist/runtime/spots/spot-manager-public.js +2 -2
- package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
- package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
- package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
- package/dist/runtime/spots/spot-outbound.js +3 -3
- package/dist/runtime/spots/spot-remote-codec.js +5 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
- package/dist/runtime/spots/spot-serial-executor.js +61 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
- package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
- package/dist/runtime/spots/spot-timer.d.ts +57 -5
- package/dist/runtime/spots/spot-timer.js +287 -103
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
- package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
- package/dist/runtime/streams/bound-session-service.d.ts +1 -1
- package/dist/runtime/streams/bound-session-service.js +6 -11
- package/dist/runtime/streams/index.d.ts +3 -2
- package/dist/runtime/streams/index.js +6 -4
- package/dist/runtime/streams/managed-stream.js +3 -2
- package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
- package/dist/runtime/streams/session-actor-coordinator.js +15 -32
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
- package/dist/runtime/streams/stream-session-runtime.js +1 -4
- package/dist/runtime/workers/index.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
- package/src/contracts/Common/encoded-payload-storage.ts +6 -3
- package/src/contracts/Configuration/Builders.ts +4 -1
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
- package/src/contracts/Locations/Rows.ts +2 -0
- package/src/contracts/Spots/Contracts.ts +8 -0
- package/src/contracts/Spots/ZLinkSpot.ts +3 -3
- package/src/runtime/abort.ts +12 -0
- package/src/runtime/actors/actor-authority-publication.ts +3 -2
- package/src/runtime/actors/actor-client.ts +61 -70
- package/src/runtime/actors/actor-context.ts +49 -9
- package/src/runtime/actors/actor-handoff.ts +282 -106
- package/src/runtime/actors/actor-join-relocation.ts +2 -0
- package/src/runtime/actors/actor-local-native-join.ts +4 -0
- package/src/runtime/actors/actor-mailbox.ts +40 -2
- package/src/runtime/actors/actor-remote-joiner.ts +6 -1
- package/src/runtime/actors/actor-reply.ts +42 -0
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
- package/src/runtime/actors/actor-runtime-state.ts +2 -20
- package/src/runtime/actors/actor-source-transfer.ts +1 -34
- package/src/runtime/actors/index.ts +41 -27
- package/src/runtime/actors/session-disconnected-wire.ts +66 -0
- package/src/runtime/admission.ts +69 -34
- package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
- package/src/runtime/application-jobs/contracts.ts +2 -0
- package/src/runtime/backend/contracts/index.ts +39 -4
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
- package/src/runtime/backend/mesh-completion-table.ts +4 -0
- package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
- package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
- package/src/runtime/channels/channel-clients.ts +49 -24
- package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
- package/src/runtime/channels/channel-dispatchers.ts +116 -72
- package/src/runtime/channels/channel-envelope.ts +105 -36
- package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
- package/src/runtime/channels/channel-runtime-manager.ts +12 -5
- package/src/runtime/channels/channel-transports.ts +49 -58
- package/src/runtime/channels/client-server-location-runtime.ts +11 -10
- package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
- package/src/runtime/channels/fanout-location-runtime.ts +17 -9
- package/src/runtime/diagnostics/flow-context.ts +20 -7
- package/src/runtime/diagnostics/index.ts +1 -7
- package/src/runtime/diagnostics/message-flow.ts +47 -9
- package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
- package/src/runtime/execution/index.ts +40 -14
- package/src/runtime/execution/serial-execution-queue.ts +31 -4
- package/src/runtime/execution/state-lane.ts +7 -0
- package/src/runtime/foundation/operation-registry.ts +98 -20
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
- package/src/runtime/foundation/service-liveness-registry.ts +39 -0
- package/src/runtime/foundation/service-mailbox.ts +8 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
- package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
- package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
- package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
- package/src/runtime/foundation/service-stateful-registry.ts +38 -35
- package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
- package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
- package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
- package/src/runtime/host/actor-packet-relay.ts +113 -94
- package/src/runtime/host/actor-placement-coordinator.ts +31 -8
- package/src/runtime/host/actor-transfer-runtime.ts +104 -430
- package/src/runtime/host/application-job-queue.ts +29 -44
- package/src/runtime/host/index.ts +286 -129
- package/src/runtime/host/location-runtime-owner.ts +2 -6
- package/src/runtime/host/mesh-router-resolver.ts +13 -5
- package/src/runtime/host/remote-bound-session-relay.ts +86 -248
- package/src/runtime/host/route-mesh-runtime.ts +11 -5
- package/src/runtime/host/runtime-shutdown.ts +15 -4
- package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
- package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
- package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
- package/src/runtime/locations/auto-connect-loop.ts +22 -14
- package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
- package/src/runtime/locations/auto-connect-types.ts +0 -1
- package/src/runtime/locations/descriptor-publication.ts +7 -0
- package/src/runtime/locations/domain-store-contract.ts +5 -0
- package/src/runtime/locations/in-memory-authority-store.ts +85 -23
- package/src/runtime/locations/in-memory-location-store.ts +1 -12
- package/src/runtime/locations/index.ts +1 -0
- package/src/runtime/locations/lease-tracker.ts +2 -9
- package/src/runtime/locations/location-store-repository.ts +628 -152
- package/src/runtime/locations/relocation-blob.ts +75 -1
- package/src/runtime/locations/request-source-resolver.ts +138 -0
- package/src/runtime/locations/resolvers.ts +2 -2
- package/src/runtime/locations/runtime.ts +70 -40
- package/src/runtime/messaging/payload-codec.ts +8 -11
- package/src/runtime/messaging/request-result.ts +33 -29
- package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
- package/src/runtime/spots/index.ts +375 -281
- package/src/runtime/spots/spot-activation-registry.ts +25 -13
- package/src/runtime/spots/spot-activation-state.ts +12 -19
- package/src/runtime/spots/spot-activation.ts +170 -86
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
- package/src/runtime/spots/spot-actor-membership.ts +0 -15
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
- package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
- package/src/runtime/spots/spot-entry-activation.ts +24 -19
- package/src/runtime/spots/spot-handler-registry.ts +15 -4
- package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
- package/src/runtime/spots/spot-manager-public.ts +2 -2
- package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
- package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
- package/src/runtime/spots/spot-outbound.ts +3 -3
- package/src/runtime/spots/spot-remote-codec.ts +9 -2
- package/src/runtime/spots/spot-runtime-ports.ts +0 -1
- package/src/runtime/spots/spot-serial-executor.ts +97 -25
- package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
- package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
- package/src/runtime/spots/spot-timer.ts +413 -157
- package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
- package/src/runtime/streams/bound-session-service.ts +7 -10
- package/src/runtime/streams/index.ts +12 -6
- package/src/runtime/streams/managed-stream.ts +4 -2
- package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
- package/src/runtime/streams/session-actor-coordinator.ts +39 -88
- package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
- package/src/runtime/streams/stream-session-runtime.ts +1 -5
- package/src/runtime/workers/index.ts +1 -1
|
@@ -15,7 +15,12 @@ import { submitToRequestResult } from '../messaging/submission-result';
|
|
|
15
15
|
import { RequestResult, SubmitResult, isZLinkBackendResultError } from '../backend/runtime-values';
|
|
16
16
|
import { enumWireRejectReason } from '../protocol/service_wire_codec.generated';
|
|
17
17
|
import { SERVICE_WIRE_PREFIX_SIZE } from './service-wire-binary-primitives';
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
OperationRegistry,
|
|
20
|
+
OperationTimeoutError,
|
|
21
|
+
type OperationObserver,
|
|
22
|
+
type PendingOperation
|
|
23
|
+
} from './operation-registry';
|
|
19
24
|
import { ServiceLivenessRegistry, type ServiceLivenessTick } from './service-liveness-registry';
|
|
20
25
|
import { ServiceMailbox, type ServiceMailboxRecord } from './service-mailbox';
|
|
21
26
|
import {
|
|
@@ -68,6 +73,19 @@ export interface RawServiceRequestResult {
|
|
|
68
73
|
readonly payload?: ServiceApplicationPayload;
|
|
69
74
|
}
|
|
70
75
|
|
|
76
|
+
/** Receives observed request terminals; the context is the caller's operation kind. */
|
|
77
|
+
export type RawServiceRequestObserver = OperationObserver<RawServiceRequestResult, number>;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* A registered request. An observed remote request has no Promise; its
|
|
81
|
+
* terminal reaches the observer. Local and Promise-contract requests carry
|
|
82
|
+
* the Promise.
|
|
83
|
+
*/
|
|
84
|
+
export interface RawServiceObservedRequest {
|
|
85
|
+
readonly id: bigint;
|
|
86
|
+
readonly promise?: Promise<RawServiceRequestResult>;
|
|
87
|
+
}
|
|
88
|
+
|
|
71
89
|
type RawServiceChannelTargetSelection =
|
|
72
90
|
| { readonly kind: 'selected'; readonly peer: AdmittedServicePeer }
|
|
73
91
|
| {
|
|
@@ -85,6 +103,8 @@ type RawServiceChannelTargetSelection =
|
|
|
85
103
|
type ServiceApplicationPayloadInput = ServiceApplicationPayload | Buffer;
|
|
86
104
|
|
|
87
105
|
export interface RawServiceIngressRecord {
|
|
106
|
+
/** Source identity recorded once by the first accepting owner (Location runtime §9.3). */
|
|
107
|
+
requestSource?: import('../locations/request-source-resolver').ZLinkRequestSourceFence;
|
|
88
108
|
readonly onAdmitted?: () => void;
|
|
89
109
|
readonly command: number;
|
|
90
110
|
readonly flags: number;
|
|
@@ -160,7 +180,7 @@ export class RawServiceMeshRuntime {
|
|
|
160
180
|
readonly mailbox: ServiceMailbox;
|
|
161
181
|
readonly liveness: ServiceLivenessRegistry;
|
|
162
182
|
|
|
163
|
-
private readonly operations: OperationRegistry<RawServiceRequestResult>;
|
|
183
|
+
private readonly operations: OperationRegistry<RawServiceRequestResult, number>;
|
|
164
184
|
private readonly expectedPeers = new Map<
|
|
165
185
|
string,
|
|
166
186
|
{
|
|
@@ -339,10 +359,12 @@ export class RawServiceMeshRuntime {
|
|
|
339
359
|
if (router.disconnectRid !== undefined) {
|
|
340
360
|
router.disconnectRid(nodeRoutingId);
|
|
341
361
|
} else {
|
|
342
|
-
|
|
362
|
+
try {
|
|
363
|
+
router.disconnect(endpoint);
|
|
364
|
+
} catch (error) {
|
|
365
|
+
if (!isAlreadyDisconnectedError(error)) throw error;
|
|
366
|
+
}
|
|
343
367
|
}
|
|
344
|
-
} catch (error) {
|
|
345
|
-
if (!isAlreadyDisconnectedError(error)) throw error;
|
|
346
368
|
} finally {
|
|
347
369
|
if (current !== undefined) this.removePeer(current);
|
|
348
370
|
this.topology.forgetNotRequired(nodeRoutingId);
|
|
@@ -399,6 +421,35 @@ export class RawServiceMeshRuntime {
|
|
|
399
421
|
};
|
|
400
422
|
}
|
|
401
423
|
|
|
424
|
+
async waitForPeerRoute(
|
|
425
|
+
nodeRoutingId: string,
|
|
426
|
+
lifecycleGeneration: bigint,
|
|
427
|
+
deadlineUnixMs: bigint,
|
|
428
|
+
signal?: AbortSignal
|
|
429
|
+
): Promise<void> {
|
|
430
|
+
const remaining = deadlineUnixMs - BigInt(Date.now());
|
|
431
|
+
if (remaining <= 0n) throw new OperationTimeoutError(0n);
|
|
432
|
+
const pending = this.operations.register(Number(remaining));
|
|
433
|
+
const check = () => {
|
|
434
|
+
if (this.isPeerRouteReady(nodeRoutingId, lifecycleGeneration)) {
|
|
435
|
+
this.operations.complete(pending.id, { terminalResult: RequestResult.Ok, failureCode: 0 });
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
const unsubscribe = this.observePeerRouteChanged((rid) => {
|
|
439
|
+
if (rid === nodeRoutingId) check();
|
|
440
|
+
});
|
|
441
|
+
const abort = () => this.operations.fail(pending.id, signal?.reason);
|
|
442
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
443
|
+
try {
|
|
444
|
+
if (signal?.aborted === true) abort();
|
|
445
|
+
else check();
|
|
446
|
+
await pending.promise;
|
|
447
|
+
} finally {
|
|
448
|
+
unsubscribe();
|
|
449
|
+
signal?.removeEventListener('abort', abort);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
402
453
|
get requestStopSignal(): AbortSignal {
|
|
403
454
|
return this.applicationJobStop.signal;
|
|
404
455
|
}
|
|
@@ -426,38 +477,39 @@ export class RawServiceMeshRuntime {
|
|
|
426
477
|
for (const listener of this.peerConnectionIntentRemoved) listener(nodeRoutingId);
|
|
427
478
|
}
|
|
428
479
|
|
|
429
|
-
announcePeer(nodeRoutingId: string):
|
|
480
|
+
announcePeer(nodeRoutingId: string): boolean {
|
|
481
|
+
if (this.closed) return false;
|
|
430
482
|
const generation = this.selectedRoutes.get(nodeRoutingId);
|
|
431
|
-
if (generation === undefined) return
|
|
432
|
-
const current = () => {
|
|
433
|
-
const admission = this.topology.routeAdmission(nodeRoutingId);
|
|
434
|
-
return (
|
|
435
|
-
this.selectedRoutes.get(nodeRoutingId) === generation &&
|
|
436
|
-
!(
|
|
437
|
-
admission?.connectionId === routeConnectionId(generation) &&
|
|
438
|
-
admission.remoteAdmitReceived === true
|
|
439
|
-
) &&
|
|
440
|
-
this.peerAdmissionSealed?.() !== true
|
|
441
|
-
);
|
|
442
|
-
};
|
|
483
|
+
if (generation === undefined) return false;
|
|
443
484
|
const key = controlSendKey(nodeRoutingId, M6aServiceWireCommand.hello);
|
|
444
|
-
if (!
|
|
485
|
+
if (!this.isPeerAnnouncementCurrent(nodeRoutingId, generation)) {
|
|
445
486
|
this.controlSends.delete(key);
|
|
446
|
-
return
|
|
487
|
+
return false;
|
|
447
488
|
}
|
|
489
|
+
const current = () => this.isPeerAnnouncementCurrent(nodeRoutingId, generation);
|
|
448
490
|
const existing = this.controlSends.get(key);
|
|
449
491
|
const hello =
|
|
450
492
|
existing?.current?.() === true
|
|
451
493
|
? existing.hello!
|
|
452
494
|
: encodeRouteMeshAdmission(M6aServiceWireCommand.hello, this.topology.localDescriptor());
|
|
453
|
-
return
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
495
|
+
return this.startControlSend(
|
|
496
|
+
nodeRoutingId,
|
|
497
|
+
M6aServiceWireCommand.hello,
|
|
498
|
+
() => this.submitControl(nodeRoutingId, [hello]),
|
|
499
|
+
current,
|
|
500
|
+
hello
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
private isPeerAnnouncementCurrent(nodeRoutingId: string, generation: bigint): boolean {
|
|
505
|
+
const admission = this.topology.routeAdmission(nodeRoutingId);
|
|
506
|
+
return (
|
|
507
|
+
this.selectedRoutes.get(nodeRoutingId) === generation &&
|
|
508
|
+
!(
|
|
509
|
+
admission?.connectionId === routeConnectionId(generation) &&
|
|
510
|
+
admission.remoteAdmitReceived === true
|
|
511
|
+
) &&
|
|
512
|
+
this.peerAdmissionSealed?.() !== true
|
|
461
513
|
);
|
|
462
514
|
}
|
|
463
515
|
|
|
@@ -562,8 +614,32 @@ export class RawServiceMeshRuntime {
|
|
|
562
614
|
payload: ServiceApplicationPayloadInput,
|
|
563
615
|
timeoutMs: number,
|
|
564
616
|
onAdmitted?: () => void
|
|
565
|
-
): PendingOperation<RawServiceRequestResult
|
|
566
|
-
|
|
617
|
+
): PendingOperation<RawServiceRequestResult>;
|
|
618
|
+
requestToNode(
|
|
619
|
+
targetNodeRoutingId: string,
|
|
620
|
+
payload: ServiceApplicationPayloadInput,
|
|
621
|
+
timeoutMs: number,
|
|
622
|
+
onAdmitted: (() => void) | undefined,
|
|
623
|
+
observer: RawServiceRequestObserver,
|
|
624
|
+
operationKind: number
|
|
625
|
+
): RawServiceObservedRequest;
|
|
626
|
+
requestToNode(
|
|
627
|
+
targetNodeRoutingId: string,
|
|
628
|
+
payload: ServiceApplicationPayloadInput,
|
|
629
|
+
timeoutMs: number,
|
|
630
|
+
onAdmitted?: () => void,
|
|
631
|
+
observer?: RawServiceRequestObserver,
|
|
632
|
+
operationKind?: number
|
|
633
|
+
): RawServiceObservedRequest {
|
|
634
|
+
return this.requestToTarget(
|
|
635
|
+
targetNodeRoutingId,
|
|
636
|
+
payload,
|
|
637
|
+
timeoutMs,
|
|
638
|
+
undefined,
|
|
639
|
+
onAdmitted,
|
|
640
|
+
observer,
|
|
641
|
+
operationKind
|
|
642
|
+
);
|
|
567
643
|
}
|
|
568
644
|
|
|
569
645
|
requestToChannel(
|
|
@@ -571,11 +647,27 @@ export class RawServiceMeshRuntime {
|
|
|
571
647
|
payload: ServiceApplicationPayloadInput,
|
|
572
648
|
timeoutMs: number,
|
|
573
649
|
onAdmitted?: () => void
|
|
574
|
-
): PendingOperation<RawServiceRequestResult
|
|
650
|
+
): PendingOperation<RawServiceRequestResult>;
|
|
651
|
+
requestToChannel(
|
|
652
|
+
channelName: string,
|
|
653
|
+
payload: ServiceApplicationPayloadInput,
|
|
654
|
+
timeoutMs: number,
|
|
655
|
+
onAdmitted: (() => void) | undefined,
|
|
656
|
+
observer: RawServiceRequestObserver,
|
|
657
|
+
operationKind: number
|
|
658
|
+
): RawServiceObservedRequest;
|
|
659
|
+
requestToChannel(
|
|
660
|
+
channelName: string,
|
|
661
|
+
payload: ServiceApplicationPayloadInput,
|
|
662
|
+
timeoutMs: number,
|
|
663
|
+
onAdmitted?: () => void,
|
|
664
|
+
observer?: RawServiceRequestObserver,
|
|
665
|
+
operationKind?: number
|
|
666
|
+
): RawServiceObservedRequest {
|
|
575
667
|
const selection = this.selectChannelTarget(channelName);
|
|
576
668
|
if (selection.kind !== 'selected') {
|
|
577
|
-
const pending = this.
|
|
578
|
-
this.
|
|
669
|
+
const pending = this.registerRequest(timeoutMs, observer, operationKind);
|
|
670
|
+
this.completeRequest(pending, selection.requestResult);
|
|
579
671
|
return pending;
|
|
580
672
|
}
|
|
581
673
|
return this.requestToTarget(
|
|
@@ -583,10 +675,45 @@ export class RawServiceMeshRuntime {
|
|
|
583
675
|
payload,
|
|
584
676
|
timeoutMs,
|
|
585
677
|
channelName,
|
|
586
|
-
onAdmitted
|
|
678
|
+
onAdmitted,
|
|
679
|
+
observer,
|
|
680
|
+
operationKind
|
|
587
681
|
);
|
|
588
682
|
}
|
|
589
683
|
|
|
684
|
+
/**
|
|
685
|
+
* One pending entry per request: an observed request reports its terminal
|
|
686
|
+
* to the caller's observer; any other request keeps the Promise contract.
|
|
687
|
+
*/
|
|
688
|
+
private registerRequest(
|
|
689
|
+
timeoutMs: number,
|
|
690
|
+
observer: RawServiceRequestObserver | undefined,
|
|
691
|
+
operationKind: number | undefined
|
|
692
|
+
): RawServiceObservedRequest {
|
|
693
|
+
return observer === undefined
|
|
694
|
+
? this.operations.register(timeoutMs)
|
|
695
|
+
: { id: this.operations.registerObserved(timeoutMs, observer, operationKind) };
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* An observed caller learns the operation id only when the request call
|
|
700
|
+
* returns, so a terminal decided inside that call is delivered after it.
|
|
701
|
+
*/
|
|
702
|
+
private completeRequest(
|
|
703
|
+
pending: RawServiceObservedRequest,
|
|
704
|
+
result: RawServiceRequestResult
|
|
705
|
+
): void {
|
|
706
|
+
if (pending.promise === undefined)
|
|
707
|
+
queueMicrotask(() => this.operations.complete(pending.id, result));
|
|
708
|
+
else this.operations.complete(pending.id, result);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
private failRequest(pending: RawServiceObservedRequest, error: unknown): void {
|
|
712
|
+
if (pending.promise === undefined)
|
|
713
|
+
queueMicrotask(() => this.operations.fail(pending.id, error));
|
|
714
|
+
else this.operations.fail(pending.id, error);
|
|
715
|
+
}
|
|
716
|
+
|
|
590
717
|
private selectChannelTarget(channelName: string): RawServiceChannelTargetSelection {
|
|
591
718
|
const selected = this.topology.selectChannel(channelName, (peer) =>
|
|
592
719
|
this.isPeerRouteReady(peer.descriptor.nodeRoutingId)
|
|
@@ -1043,6 +1170,7 @@ export class RawServiceMeshRuntime {
|
|
|
1043
1170
|
]);
|
|
1044
1171
|
} else if (header.command === M6aServiceWireCommand.admit) {
|
|
1045
1172
|
this.controlSends.delete(helloKey);
|
|
1173
|
+
this.refreshAdmissionPending(nowMs);
|
|
1046
1174
|
if (result === 'notRequired') {
|
|
1047
1175
|
this.retireNotRequiredExpectedPeer(received.sourceRid, descriptor.advertisedEndpoint);
|
|
1048
1176
|
} else if (
|
|
@@ -1126,12 +1254,7 @@ export class RawServiceMeshRuntime {
|
|
|
1126
1254
|
if (
|
|
1127
1255
|
header.flags !== 0 ||
|
|
1128
1256
|
received.parts.length !== 2 ||
|
|
1129
|
-
!
|
|
1130
|
-
M6aServiceWireCommand.nodeSend,
|
|
1131
|
-
M6aServiceWireCommand.nodeRequest,
|
|
1132
|
-
M6aServiceWireCommand.channelSend,
|
|
1133
|
-
M6aServiceWireCommand.channelRequest
|
|
1134
|
-
].includes(header.command as never)
|
|
1257
|
+
!isApplicationEnvelopeCommand(header.command)
|
|
1135
1258
|
) {
|
|
1136
1259
|
return 'protocolError';
|
|
1137
1260
|
}
|
|
@@ -1170,9 +1293,9 @@ export class RawServiceMeshRuntime {
|
|
|
1170
1293
|
parts: received.parts,
|
|
1171
1294
|
sourceRoutingId: received.sourceRid,
|
|
1172
1295
|
sourceRoute: received.sourceRoute,
|
|
1173
|
-
|
|
1296
|
+
reply: received.reply,
|
|
1174
1297
|
requestSequence: received.requestSeq,
|
|
1175
|
-
|
|
1298
|
+
correlation,
|
|
1176
1299
|
applicationJob
|
|
1177
1300
|
});
|
|
1178
1301
|
if (accepted) return 'application';
|
|
@@ -1200,10 +1323,42 @@ export class RawServiceMeshRuntime {
|
|
|
1200
1323
|
return this.operations.size;
|
|
1201
1324
|
}
|
|
1202
1325
|
|
|
1326
|
+
cancelPendingOperations(reason: unknown): void {
|
|
1327
|
+
this.operations.failAll(reason);
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
/**
|
|
1331
|
+
* The next management deadline of this node (spec 08 §4.2): request expiry,
|
|
1332
|
+
* liveness probe or timeout, or an owned HELLO exchange still awaiting
|
|
1333
|
+
* ADMIT, which keeps the existing announce cadence.
|
|
1334
|
+
*/
|
|
1335
|
+
nextMaintenanceDeadlineMs(nowMs: number): number {
|
|
1336
|
+
this.refreshAdmissionPending(nowMs);
|
|
1337
|
+
return Math.min(this.operations.nextDeadlineMs(), this.liveness.nextDeadlineMs());
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
private refreshAdmissionPending(nowMs: number): void {
|
|
1341
|
+
let pending = false;
|
|
1342
|
+
if (!this.closed && this.controlSends.size !== 0) {
|
|
1343
|
+
for (const nodeRoutingId of this.selectedRoutes.keys()) {
|
|
1344
|
+
const exchange = this.controlSends.get(
|
|
1345
|
+
controlSendKey(nodeRoutingId, M6aServiceWireCommand.hello)
|
|
1346
|
+
);
|
|
1347
|
+
if (exchange?.current?.() === true) {
|
|
1348
|
+
pending = true;
|
|
1349
|
+
break;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
this.liveness.setAdmissionPending(pending, nowMs);
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1203
1356
|
tickLiveness(nowMs = performance.now()): ServiceLivenessTick {
|
|
1357
|
+
const admissionDue = this.liveness.tickAdmission(nowMs);
|
|
1204
1358
|
const result = this.liveness.tick(nowMs);
|
|
1205
1359
|
this.requireStarted();
|
|
1206
|
-
|
|
1360
|
+
if (admissionDue)
|
|
1361
|
+
for (const nodeRoutingId of this.selectedRoutes.keys()) void this.announcePeer(nodeRoutingId);
|
|
1207
1362
|
for (const probe of result.probes) {
|
|
1208
1363
|
const parts = [
|
|
1209
1364
|
livenessCodec.encodeLivenessRecord({
|
|
@@ -1257,6 +1412,7 @@ export class RawServiceMeshRuntime {
|
|
|
1257
1412
|
for (const nodeRoutingId of selected) this.notifyPeerRouteChanged(nodeRoutingId);
|
|
1258
1413
|
// A new selected route admits only through a new handshake.
|
|
1259
1414
|
for (const nodeRoutingId of selected) await this.announcePeer(nodeRoutingId);
|
|
1415
|
+
this.refreshAdmissionPending(performance.now());
|
|
1260
1416
|
return changes;
|
|
1261
1417
|
}
|
|
1262
1418
|
|
|
@@ -1289,15 +1445,16 @@ export class RawServiceMeshRuntime {
|
|
|
1289
1445
|
payload: ServiceApplicationPayloadInput,
|
|
1290
1446
|
timeoutMs: number,
|
|
1291
1447
|
channelName?: string,
|
|
1292
|
-
onAdmitted?: () => void
|
|
1293
|
-
|
|
1448
|
+
onAdmitted?: () => void,
|
|
1449
|
+
observer?: RawServiceRequestObserver,
|
|
1450
|
+
operationKind?: number
|
|
1451
|
+
): RawServiceObservedRequest {
|
|
1294
1452
|
const correlation = this.nextCorrelation++;
|
|
1295
1453
|
const header =
|
|
1296
1454
|
channelName === undefined
|
|
1297
1455
|
? encodeNodeRequestHeader(correlation)
|
|
1298
1456
|
: encodeChannelRequestHeader(correlation, channelName);
|
|
1299
1457
|
const encodedPayload = this.applicationFrame(payload);
|
|
1300
|
-
const pending = this.operations.register(timeoutMs);
|
|
1301
1458
|
let selectedTargetNodeRoutingId = targetNodeRoutingId;
|
|
1302
1459
|
if (
|
|
1303
1460
|
selectedTargetNodeRoutingId !== this.descriptor.nodeRoutingId &&
|
|
@@ -1325,6 +1482,9 @@ export class RawServiceMeshRuntime {
|
|
|
1325
1482
|
}
|
|
1326
1483
|
}
|
|
1327
1484
|
if (selectedTargetNodeRoutingId === this.descriptor.nodeRoutingId) {
|
|
1485
|
+
// The local admission path aborts its capacity wait on the terminal
|
|
1486
|
+
// Promise, so a local request always keeps the Promise entry.
|
|
1487
|
+
const pending = this.operations.register(timeoutMs);
|
|
1328
1488
|
const parts = [header, encodedPayload];
|
|
1329
1489
|
const capacityStop = new AbortController();
|
|
1330
1490
|
void pending.promise.finally(() => capacityStop.abort()).catch(() => undefined);
|
|
@@ -1369,12 +1529,13 @@ export class RawServiceMeshRuntime {
|
|
|
1369
1529
|
})().catch((error) => this.operations.fail(pending.id, error));
|
|
1370
1530
|
return pending;
|
|
1371
1531
|
}
|
|
1532
|
+
const pending = this.registerRequest(timeoutMs, observer, operationKind);
|
|
1372
1533
|
const selectedPeer = this.topology.admittedPeer(selectedTargetNodeRoutingId);
|
|
1373
1534
|
if (selectedPeer === undefined) {
|
|
1374
1535
|
// Logical target selection is the requester's decision: an RID that is
|
|
1375
1536
|
// not an admitted peer is not a target. Whether an admitted target's
|
|
1376
1537
|
// route can carry the request is Core's REQUEST result.
|
|
1377
|
-
this.
|
|
1538
|
+
this.completeRequest(pending, {
|
|
1378
1539
|
terminalResult: RequestResult.NotFound,
|
|
1379
1540
|
failureCode: REQUEST_TARGET_NOT_FOUND_FAILURE_CODE
|
|
1380
1541
|
});
|
|
@@ -1391,7 +1552,7 @@ export class RawServiceMeshRuntime {
|
|
|
1391
1552
|
onAdmitted
|
|
1392
1553
|
);
|
|
1393
1554
|
} catch (error) {
|
|
1394
|
-
this.
|
|
1555
|
+
this.failRequest(pending, error);
|
|
1395
1556
|
return pending;
|
|
1396
1557
|
}
|
|
1397
1558
|
void request.then(
|
|
@@ -1568,6 +1729,8 @@ export class RawServiceMeshRuntime {
|
|
|
1568
1729
|
hello?: Uint8Array
|
|
1569
1730
|
): boolean {
|
|
1570
1731
|
const key = controlSendKey(target, command);
|
|
1732
|
+
if (command === M6aServiceWireCommand.hello)
|
|
1733
|
+
this.liveness.setAdmissionPending(true, performance.now());
|
|
1571
1734
|
const existing = this.controlSends.get(key);
|
|
1572
1735
|
if (
|
|
1573
1736
|
existing !== undefined &&
|
|
@@ -1607,16 +1770,19 @@ export class RawServiceMeshRuntime {
|
|
|
1607
1770
|
() => {},
|
|
1608
1771
|
(error) => {
|
|
1609
1772
|
completeSend();
|
|
1610
|
-
|
|
1773
|
+
this.reportInfrastructureFailure(error);
|
|
1611
1774
|
}
|
|
1612
1775
|
);
|
|
1613
|
-
this.infrastructureTaskRunner?.runDetached('RouteMesh control SEND', async () => {
|
|
1614
|
-
await task;
|
|
1615
|
-
});
|
|
1616
1776
|
return true;
|
|
1617
1777
|
}
|
|
1618
1778
|
|
|
1619
|
-
|
|
1779
|
+
reportInfrastructureFailure(error: unknown): void {
|
|
1780
|
+
if (this.infrastructureTaskRunner !== undefined) {
|
|
1781
|
+
this.infrastructureTaskRunner.runDetached('RouteMesh infrastructure', async () => {
|
|
1782
|
+
throw error;
|
|
1783
|
+
});
|
|
1784
|
+
return;
|
|
1785
|
+
}
|
|
1620
1786
|
this.infrastructureFailure = {
|
|
1621
1787
|
error:
|
|
1622
1788
|
this.infrastructureFailure === undefined
|
|
@@ -1662,7 +1828,7 @@ export class RawServiceMeshRuntime {
|
|
|
1662
1828
|
}
|
|
1663
1829
|
|
|
1664
1830
|
function controlSendKey(target: string, command: number): string {
|
|
1665
|
-
return
|
|
1831
|
+
return `${command}:${target}`;
|
|
1666
1832
|
}
|
|
1667
1833
|
|
|
1668
1834
|
function routeConnectionId(generation: bigint): string {
|
|
@@ -1674,20 +1840,31 @@ function routeConnectionId(generation: bigint): string {
|
|
|
1674
1840
|
* not application NodeSend(16) envelopes. Keep this list closed: a bare
|
|
1675
1841
|
* record outside the frozen control vocabulary remains a protocol error.
|
|
1676
1842
|
*/
|
|
1843
|
+
const BARE_INFRASTRUCTURE_CONTROLS: ReadonlySet<number> = new Set<number>([
|
|
1844
|
+
ServiceWireCommand.relocationReady,
|
|
1845
|
+
ServiceWireCommand.relocationData,
|
|
1846
|
+
ServiceWireCommand.replyRelay,
|
|
1847
|
+
ServiceWireCommand.relocationCutover,
|
|
1848
|
+
ServiceWireCommand.relocationPrepare,
|
|
1849
|
+
ServiceWireCommand.sessionRelocationSeal,
|
|
1850
|
+
ServiceWireCommand.sessionRelocationSealed,
|
|
1851
|
+
ServiceWireCommand.sessionRelocationRoute,
|
|
1852
|
+
ServiceWireCommand.replyRelayAck,
|
|
1853
|
+
ServiceWireCommand.relocationState,
|
|
1854
|
+
ServiceWireCommand.relocationFailed
|
|
1855
|
+
]);
|
|
1856
|
+
|
|
1677
1857
|
function isBareInfrastructureControl(command: number): boolean {
|
|
1678
|
-
return
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
ServiceWireCommand.relocationState,
|
|
1689
|
-
ServiceWireCommand.relocationFailed
|
|
1690
|
-
].includes(command as never);
|
|
1858
|
+
return BARE_INFRASTRUCTURE_CONTROLS.has(command);
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
function isApplicationEnvelopeCommand(command: number): boolean {
|
|
1862
|
+
return (
|
|
1863
|
+
command === M6aServiceWireCommand.nodeSend ||
|
|
1864
|
+
command === M6aServiceWireCommand.nodeRequest ||
|
|
1865
|
+
command === M6aServiceWireCommand.channelSend ||
|
|
1866
|
+
command === M6aServiceWireCommand.channelRequest
|
|
1867
|
+
);
|
|
1691
1868
|
}
|
|
1692
1869
|
|
|
1693
1870
|
function protocolCommand(parts: readonly Uint8Array[]): { readonly command?: number } {
|
|
@@ -54,9 +54,20 @@ export class ServiceLivenessConnection {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/** Uses monotonic milliseconds and never treats application traffic as a probe ACK. */
|
|
57
|
+
const NO_LIVENESS_WORK: ServiceLivenessTick = Object.freeze({
|
|
58
|
+
probes: Object.freeze([]) as readonly ServiceProbe[],
|
|
59
|
+
timedOutNodes: Object.freeze([]) as readonly string[]
|
|
60
|
+
});
|
|
61
|
+
|
|
57
62
|
export class ServiceLivenessRegistry {
|
|
58
63
|
private readonly peers = new Map<string, ServiceLivenessConnection>();
|
|
59
64
|
private nextProbeId = 1n;
|
|
65
|
+
/**
|
|
66
|
+
* The earliest probe or timeout among admitted peers. Received traffic only
|
|
67
|
+
* extends a peer's deadline, so this stays a lower bound between ticks.
|
|
68
|
+
*/
|
|
69
|
+
private nextDueMs = Number.POSITIVE_INFINITY;
|
|
70
|
+
private admissionActivityMs?: number;
|
|
60
71
|
|
|
61
72
|
constructor(
|
|
62
73
|
private readonly probeIntervalMs = DEFAULT_SERVICE_PROBE_INTERVAL_MS,
|
|
@@ -89,9 +100,33 @@ export class ServiceLivenessRegistry {
|
|
|
89
100
|
this.peerTimeoutMs
|
|
90
101
|
);
|
|
91
102
|
this.peers.set(nodeRoutingId, admitted);
|
|
103
|
+
this.nextDueMs = Math.min(this.nextDueMs, admitted.nextProbeMs, admitted.deadlineMs);
|
|
92
104
|
return admitted;
|
|
93
105
|
}
|
|
94
106
|
|
|
107
|
+
/** When the next tick has probe or timeout work (spec 08 §4.2 management deadline). */
|
|
108
|
+
nextDeadlineMs(): number {
|
|
109
|
+
return Math.min(this.nextDueMs, this.nextAdmissionDeadlineMs());
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Pending admission shares the existing liveness management cadence (MeshNode §7.1). */
|
|
113
|
+
setAdmissionPending(pending: boolean, nowMs: number): void {
|
|
114
|
+
if (pending) this.admissionActivityMs ??= nowMs;
|
|
115
|
+
else this.admissionActivityMs = undefined;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private nextAdmissionDeadlineMs(): number {
|
|
119
|
+
return this.admissionActivityMs === undefined
|
|
120
|
+
? Number.POSITIVE_INFINITY
|
|
121
|
+
: this.admissionActivityMs + this.probeIntervalMs;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
tickAdmission(nowMs: number): boolean {
|
|
125
|
+
if (nowMs < this.nextAdmissionDeadlineMs()) return false;
|
|
126
|
+
this.admissionActivityMs = nowMs;
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
|
|
95
130
|
recordReceived(connection: ServiceLivenessConnection, nowMs: number): void {
|
|
96
131
|
connection.recordReceived(nowMs);
|
|
97
132
|
}
|
|
@@ -127,8 +162,10 @@ export class ServiceLivenessRegistry {
|
|
|
127
162
|
}
|
|
128
163
|
|
|
129
164
|
tick(nowMs: number): ServiceLivenessTick {
|
|
165
|
+
if (nowMs < this.nextDeadlineMs()) return NO_LIVENESS_WORK;
|
|
130
166
|
const probes: ServiceProbe[] = [];
|
|
131
167
|
const timedOutNodes: string[] = [];
|
|
168
|
+
let nextDueMs = Number.POSITIVE_INFINITY;
|
|
132
169
|
for (const [nodeRoutingId, peer] of this.peers) {
|
|
133
170
|
if (peer.isExpired(nowMs)) {
|
|
134
171
|
timedOutNodes.push(nodeRoutingId);
|
|
@@ -138,7 +175,9 @@ export class ServiceLivenessRegistry {
|
|
|
138
175
|
const probeId = peer.tryGetProbe(nowMs, this.allocateProbeId);
|
|
139
176
|
if (probeId !== undefined)
|
|
140
177
|
probes.push({ nodeRoutingId, connectionId: peer.connectionId, probeId });
|
|
178
|
+
nextDueMs = Math.min(nextDueMs, peer.nextProbeMs, peer.deadlineMs);
|
|
141
179
|
}
|
|
180
|
+
this.nextDueMs = nextDueMs;
|
|
142
181
|
timedOutNodes.sort();
|
|
143
182
|
return { probes, timedOutNodes };
|
|
144
183
|
}
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import type { ApplicationJobRecordLease } from '../application-jobs/application-ingress-record-owner';
|
|
2
2
|
import type { ReceiveRecord } from './service-runtime-contracts';
|
|
3
|
+
import type { RawServiceIngressRecord } from './raw-service-mesh-runtime';
|
|
3
4
|
|
|
4
5
|
export type ServiceMailboxDomain = 'application' | 'infrastructure';
|
|
5
6
|
|
|
7
|
+
export interface ServiceMailboxDispatchOwner {
|
|
8
|
+
prepareDispatch(record: ServiceMailboxRecord, signal: AbortSignal): boolean | Promise<boolean>;
|
|
9
|
+
}
|
|
10
|
+
|
|
6
11
|
export interface ServiceMailboxRecord {
|
|
12
|
+
readonly sourcePreparationOwner?: ServiceMailboxDispatchOwner;
|
|
13
|
+
readonly ingress?: RawServiceIngressRecord;
|
|
7
14
|
readonly owner: string;
|
|
8
15
|
readonly domain: ServiceMailboxDomain;
|
|
9
16
|
parts: readonly Uint8Array[];
|
|
10
17
|
readonly sourceRoutingId?: string;
|
|
18
|
+
readonly requestSource?: import('../locations/request-source-resolver').ZLinkRequestSourceFence;
|
|
11
19
|
readonly sourceRoute?: Uint8Array;
|
|
12
20
|
readonly requestSequence?: bigint;
|
|
13
21
|
readonly reply?: (parts: readonly Uint8Array[]) => void;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ZLinkStateLane } from '../execution/state-lane';
|
|
3
|
-
|
|
4
|
-
const detachedStateLaneResource = new AsyncResource('zlink:service-maintenance-runtime');
|
|
1
|
+
import { startOutsideStateLane, ZLinkStateLane } from '../execution/state-lane';
|
|
5
2
|
|
|
6
3
|
export type ServiceMaintenanceKind = 'retire' | 'shutdown';
|
|
7
4
|
export type ServiceMaintenanceState =
|
|
@@ -248,7 +245,3 @@ export class ServiceMaintenanceRuntime {
|
|
|
248
245
|
for (const observer of publication.observers) observer(publication.snapshot);
|
|
249
246
|
}
|
|
250
247
|
}
|
|
251
|
-
|
|
252
|
-
function startOutsideStateLane<T>(work: () => T): T {
|
|
253
|
-
return detachedStateLaneResource.runInAsyncScope(work);
|
|
254
|
-
}
|