@zlink-systems/framework 0.21.0 → 0.23.0
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/ZLinkMessage.js +5 -5
- package/dist/contracts/Configuration/CodecContentType.js +5 -7
- package/dist/contracts/Configuration/DiagnosticsValidation.js +1 -6
- package/dist/contracts/Configuration/EndpointNotation.js +4 -8
- package/dist/contracts/Configuration/Registration.js +14 -11
- package/dist/contracts/Configuration/RegistrationBuilders.js +32 -25
- package/dist/contracts/Configuration/RegistrationNormalizers.js +25 -26
- package/dist/contracts/Configuration/RegistrationValidators.js +36 -38
- package/dist/contracts/Configuration/SendTimeoutValidation.js +4 -4
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +7 -7
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -0
- package/dist/contracts/Handlers/JsonContract.js +23 -11
- package/dist/contracts/Spots/SpotKind.js +16 -8
- package/dist/contracts/Streams/IZLinkSession.d.ts +2 -1
- package/dist/location-store-integration.js +16 -16
- package/dist/nest-integration.js +17 -11
- package/dist/runtime/abort.js +9 -5
- package/dist/runtime/actors/actor-authority-payload-codec.js +12 -16
- package/dist/runtime/actors/actor-authority-publication.js +18 -17
- package/dist/runtime/actors/actor-client.js +83 -63
- package/dist/runtime/actors/actor-context.js +28 -22
- package/dist/runtime/actors/actor-creation.js +4 -3
- package/dist/runtime/actors/actor-handoff.js +89 -92
- package/dist/runtime/actors/actor-join-deferred-scope.d.ts +0 -1
- package/dist/runtime/actors/actor-join-deferred-scope.js +0 -18
- package/dist/runtime/actors/actor-local-native-join.js +18 -19
- package/dist/runtime/actors/actor-mailbox.js +1 -1
- package/dist/runtime/actors/actor-message-follow-context.js +24 -21
- package/dist/runtime/actors/actor-packet-relay-wire.js +1 -3
- package/dist/runtime/actors/actor-remote-joiner.js +20 -17
- package/dist/runtime/actors/actor-remote-wire.js +6 -7
- package/dist/runtime/actors/actor-runtime-state.js +87 -81
- package/dist/runtime/actors/actor-transfer-registry.js +3 -5
- package/dist/runtime/actors/bound-session-wire.js +14 -9
- package/dist/runtime/actors/deferred-join-accepted-journal.js +160 -130
- package/dist/runtime/actors/index.js +2 -5
- package/dist/runtime/actors/post-commit-actor-binder.js +3 -6
- package/dist/runtime/actors/post-commit-actor-location.js +1 -1
- package/dist/runtime/actors/spot-actor-dispatch.js +5 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +4 -4
- package/dist/runtime/admission.js +2 -6
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +2 -6
- package/dist/runtime/application-jobs/receive-flow-controller.js +11 -12
- package/dist/runtime/backend/contracts/index.d.ts +1 -0
- package/dist/runtime/backend/mesh-completion-table.js +1 -3
- package/dist/runtime/backend/mesh-dispatch-pump.js +12 -16
- package/dist/runtime/backend/node/node-backend-adapter-factory.js +1 -3
- package/dist/runtime/backend/node/node-backend-adapter-support.js +26 -17
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +4 -3
- package/dist/runtime/backend/node/node-raw-binding-port.js +7 -6
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +3 -0
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +134 -118
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +12 -13
- package/dist/runtime/backend/runtime-message.js +3 -3
- package/dist/runtime/backend/runtime-values.d.ts +2 -2
- package/dist/runtime/backend/runtime-values.js +4 -5
- package/dist/runtime/channels/channel-clients.js +27 -24
- package/dist/runtime/channels/channel-dispatch-pipeline.js +12 -20
- package/dist/runtime/channels/channel-dispatch-services.js +7 -4
- package/dist/runtime/channels/channel-dispatchers.js +9 -9
- package/dist/runtime/channels/channel-envelope-inspection.js +16 -13
- package/dist/runtime/channels/channel-envelope.js +83 -47
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-receive-loops.js +20 -22
- package/dist/runtime/channels/channel-receive-task-tracker.js +1 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +61 -56
- package/dist/runtime/channels/channel-runtime-manager.js +18 -9
- package/dist/runtime/channels/channel-socket-registry.js +126 -123
- package/dist/runtime/channels/channel-transports.js +46 -42
- package/dist/runtime/channels/client-server-location-runtime.js +32 -40
- package/dist/runtime/channels/client-server-service-wire.js +29 -22
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -0
- package/dist/runtime/channels/dispatch-error-reporter.js +9 -39
- package/dist/runtime/channels/fanout-location-runtime.js +34 -47
- package/dist/runtime/channels/fanout-service-wire.js +3 -5
- package/dist/runtime/channels/local-spot-route-transport.js +7 -1
- package/dist/runtime/channels/route-member-snapshot.js +3 -3
- package/dist/runtime/channels/source-spot-router.js +6 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +5 -2
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +2 -2
- package/dist/runtime/channels/spot-route-target-resolver.js +6 -6
- package/dist/runtime/diagnostics/dispatch-error-details.d.ts +6 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +55 -0
- package/dist/runtime/diagnostics/flow-context.d.ts +2 -1
- package/dist/runtime/diagnostics/flow-context.js +2 -2
- package/dist/runtime/diagnostics/index.js +38 -10
- package/dist/runtime/diagnostics/message-flow.js +58 -42
- package/dist/runtime/diagnostics/runtime-metrics.js +18 -9
- package/dist/runtime/diagnostics/runtime-observation-queue.js +8 -10
- package/dist/runtime/diagnostics/topology-runtime-projections.js +17 -10
- package/dist/runtime/execution/index.js +7 -6
- package/dist/runtime/execution/serial-execution-queue.js +12 -18
- package/dist/runtime/execution/state-lane.js +2 -2
- package/dist/runtime/foundation/actor-join-recovery-codec.js +31 -27
- package/dist/runtime/foundation/event-loop-resources.js +4 -4
- package/dist/runtime/foundation/message-follow-suppression-registry.js +4 -4
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +4 -2
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +169 -144
- package/dist/runtime/foundation/route-mesh-connection-policy.js +4 -4
- package/dist/runtime/foundation/runtime-state-projections.js +22 -11
- package/dist/runtime/foundation/service-authority-payload-codec.js +13 -15
- package/dist/runtime/foundation/service-discovery-registry.js +35 -33
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +20 -22
- package/dist/runtime/foundation/service-liveness-registry.js +16 -12
- package/dist/runtime/foundation/service-maintenance-runtime.js +2 -4
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +24 -24
- package/dist/runtime/foundation/service-relocation-object-owner.js +6 -6
- package/dist/runtime/foundation/service-relocation-runtime.js +137 -94
- package/dist/runtime/foundation/service-runtime-contracts.js +5 -5
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +1 -0
- package/dist/runtime/foundation/service-stateful-registry.js +24 -23
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +4 -0
- package/dist/runtime/foundation/service-stateful-runtime.js +461 -439
- package/dist/runtime/foundation/service-stateful-wire-codec.js +95 -98
- package/dist/runtime/foundation/service-topology-registry.d.ts +1 -0
- package/dist/runtime/foundation/service-topology-registry.js +105 -96
- package/dist/runtime/foundation/service-weighted-selection.js +6 -11
- package/dist/runtime/foundation/service-wire-binary-primitives.js +5 -6
- package/dist/runtime/foundation/service-wire-m6a-codec.js +46 -35
- package/dist/runtime/framework-errors-internal.js +7 -10
- package/dist/runtime/handlers/handler-instance-scope.js +4 -5
- package/dist/runtime/handlers/index.js +3 -1
- package/dist/runtime/host/actor-packet-relay.js +74 -70
- package/dist/runtime/host/actor-placement-coordinator.js +29 -31
- package/dist/runtime/host/actor-runtime-options-factory.js +12 -14
- package/dist/runtime/host/actor-transfer-authority-runtime.js +7 -9
- package/dist/runtime/host/actor-transfer-runtime.js +176 -153
- package/dist/runtime/host/application-job-queue.js +18 -22
- package/dist/runtime/host/bound-session-relay.js +3 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +31 -14
- package/dist/runtime/host/host-capacity-status.js +8 -4
- package/dist/runtime/host/index.js +245 -228
- package/dist/runtime/host/instance-activation-authority.js +93 -96
- package/dist/runtime/host/location-runtime-owner.js +16 -14
- package/dist/runtime/host/mesh-router-resolver.js +11 -13
- package/dist/runtime/host/relocation-direct-transfer.js +10 -9
- package/dist/runtime/host/remote-actor-join-receiver.js +20 -15
- package/dist/runtime/host/remote-actor-packet-target-store.js +18 -22
- package/dist/runtime/host/remote-bound-session-relay.js +97 -73
- package/dist/runtime/host/route-mesh-runtime.js +64 -69
- package/dist/runtime/host/runtime-shutdown.js +1 -2
- package/dist/runtime/host/service-relocation-host-runtime.js +586 -511
- package/dist/runtime/host/spot-address-transport.js +69 -71
- package/dist/runtime/host/spot-runtime-options-factory.js +30 -29
- package/dist/runtime/host/stateful-authority-route-runtime.js +65 -68
- package/dist/runtime/host/user-spot-creation-coordinator.js +61 -67
- package/dist/runtime/locations/actor-location-claims.js +26 -20
- package/dist/runtime/locations/aggregate-inventory-store.js +72 -75
- package/dist/runtime/locations/authority-key-codec.js +7 -7
- package/dist/runtime/locations/auto-connect-loop.js +3 -3
- package/dist/runtime/locations/auto-connect-planner.js +25 -19
- package/dist/runtime/locations/auto-connect-reconciler.js +51 -31
- package/dist/runtime/locations/in-memory-authority-store.js +128 -118
- package/dist/runtime/locations/in-memory-location-store.js +195 -168
- package/dist/runtime/locations/in-memory-provider-location-store.js +8 -10
- package/dist/runtime/locations/key-codec.js +1 -1
- package/dist/runtime/locations/lease-tracker.js +23 -21
- package/dist/runtime/locations/lifecycle.js +4 -5
- package/dist/runtime/locations/location-store-repository.js +368 -324
- package/dist/runtime/locations/opaque-record-key.js +2 -2
- package/dist/runtime/locations/resolvers.js +73 -82
- package/dist/runtime/locations/runtime.js +68 -63
- package/dist/runtime/locations/spot-location-claims.js +39 -35
- package/dist/runtime/messaging/framework-json-v1.js +7 -7
- package/dist/runtime/messaging/packet-name.js +7 -6
- package/dist/runtime/messaging/payload-codec.js +21 -18
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +30 -2
- package/dist/runtime/protocol/service_wire_codec.generated.js +1671 -234
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +20 -18
- package/dist/runtime/routing-id.js +3 -5
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +35 -31
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.js +1 -2
- package/dist/runtime/spots/index.js +209 -220
- package/dist/runtime/spots/spot-activation-registry.js +15 -14
- package/dist/runtime/spots/spot-activation-state.js +17 -15
- package/dist/runtime/spots/spot-activation.js +33 -16
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +18 -15
- package/dist/runtime/spots/spot-actor-membership.js +1 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +2 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +29 -21
- package/dist/runtime/spots/spot-actor-packet-drain.js +14 -10
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +10 -6
- package/dist/runtime/spots/spot-closing.js +3 -7
- package/dist/runtime/spots/spot-context.js +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +13 -14
- package/dist/runtime/spots/spot-handle.js +6 -3
- package/dist/runtime/spots/spot-handler-registry.js +12 -12
- package/dist/runtime/spots/spot-manager-public.js +5 -6
- package/dist/runtime/spots/spot-native-actor-join-admission.js +4 -3
- package/dist/runtime/spots/spot-node-autoconnect.js +15 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +79 -86
- package/dist/runtime/spots/spot-outbound.js +10 -14
- package/dist/runtime/spots/spot-remote-codec.js +22 -26
- package/dist/runtime/spots/spot-remote-route-codec.js +5 -7
- package/dist/runtime/spots/spot-route-packet-dispatch.js +17 -15
- package/dist/runtime/spots/spot-route-replies.js +4 -6
- package/dist/runtime/spots/spot-routed-actor-admission.js +9 -7
- package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +2 -3
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +5 -5
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +14 -10
- package/dist/runtime/spots/spot-serial-executor.js +5 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +4 -6
- package/dist/runtime/spots/spot-subscription-dispatch.js +6 -6
- package/dist/runtime/spots/spot-timer.js +26 -30
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +21 -8
- package/dist/runtime/streams/actor-session-binding-registry.js +168 -148
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -0
- package/dist/runtime/streams/actor-session-lifecycle-coordinator.js +3 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +20 -17
- package/dist/runtime/streams/bound-session-response-target.js +8 -1
- package/dist/runtime/streams/bound-session-service.d.ts +1 -0
- package/dist/runtime/streams/bound-session-service.js +14 -12
- package/dist/runtime/streams/index.js +28 -20
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +52 -31
- package/dist/runtime/streams/native-fallback-bound-session.js +21 -17
- package/dist/runtime/streams/protocol.d.ts +5 -1
- package/dist/runtime/streams/protocol.js +68 -20
- package/dist/runtime/streams/session-actor-coordinator.js +37 -41
- package/dist/runtime/streams/session-context.d.ts +9 -2
- package/dist/runtime/streams/session-context.js +50 -32
- package/dist/runtime/streams/session-local-actors.d.ts +3 -1
- package/dist/runtime/streams/session-local-actors.js +17 -2
- package/dist/runtime/streams/session-provider.js +2 -2
- package/dist/runtime/streams/session-serial-executor.js +1 -2
- package/dist/runtime/streams/stream-frame-factory.d.ts +1 -1
- package/dist/runtime/streams/stream-frame-factory.js +14 -7
- package/dist/runtime/streams/stream-session-runtime.js +112 -78
- package/dist/runtime/workers/index.js +15 -4
- package/package.json +3 -3
- package/src/contracts/Channels/RouteCalls.ts +6 -1
- package/src/contracts/Common/ZLinkMessage.ts +5 -5
- package/src/contracts/Common/ZLinkMessageMetadata.ts +4 -3
- package/src/contracts/Configuration/Builders.ts +14 -14
- package/src/contracts/Configuration/CodecContentType.ts +8 -10
- package/src/contracts/Configuration/DiagnosticsValidation.ts +1 -6
- package/src/contracts/Configuration/EndpointNotation.ts +11 -11
- package/src/contracts/Configuration/ObjectRoles.ts +1 -3
- package/src/contracts/Configuration/Registration.ts +46 -17
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +10 -8
- package/src/contracts/Configuration/RegistrationBuilders.ts +107 -96
- package/src/contracts/Configuration/RegistrationCodecRegistry.ts +9 -3
- package/src/contracts/Configuration/RegistrationNormalizers.ts +116 -84
- package/src/contracts/Configuration/RegistrationTypes.ts +21 -25
- package/src/contracts/Configuration/RegistrationValidators.ts +122 -73
- package/src/contracts/Configuration/RouteChannelInternalState.ts +1 -4
- package/src/contracts/Configuration/RuntimeEndpointConnections.ts +4 -1
- package/src/contracts/Configuration/SendTimeoutValidation.ts +6 -4
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +8 -13
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -6
- package/src/contracts/Errors/index.ts +1 -4
- package/src/contracts/Handlers/Attributes.ts +15 -9
- package/src/contracts/Handlers/IZLinkChannelHandlers.ts +24 -4
- package/src/contracts/Handlers/JsonContract.ts +53 -19
- package/src/contracts/Locations/ActorTransfer.ts +1 -5
- package/src/contracts/Locations/Authority.ts +4 -11
- package/src/contracts/Locations/Keys.ts +6 -1
- package/src/contracts/Locations/Options.ts +3 -2
- package/src/contracts/Locations/RelocationStore.ts +1 -4
- package/src/contracts/Locations/Resolvers.ts +5 -5
- package/src/contracts/Locations/RuntimeQuery.ts +6 -2
- package/src/contracts/Locations/Stores.ts +1 -2
- package/src/contracts/Locations/index.ts +2 -8
- package/src/contracts/RouteMesh/Contracts.ts +1 -7
- package/src/contracts/RouteMesh/RuntimeTopology.ts +1 -4
- package/src/contracts/Spots/Contracts.ts +2 -8
- package/src/contracts/Spots/SpotKind.ts +16 -8
- package/src/contracts/Spots/ZLinkSpot.ts +8 -11
- package/src/contracts/Streams/IZLinkSession.ts +2 -2
- package/src/contracts/Streams/IZLinkSessionActor.ts +5 -1
- package/src/contracts/Streams/IZLinkSessionPacketHandler.ts +5 -1
- package/src/internal.ts +5 -4
- package/src/location-store-integration.ts +24 -16
- package/src/nest-integration.ts +40 -25
- package/src/runtime/abort.ts +10 -4
- package/src/runtime/actors/actor-authority-payload-codec.ts +20 -29
- package/src/runtime/actors/actor-authority-publication.ts +92 -77
- package/src/runtime/actors/actor-client.ts +162 -133
- package/src/runtime/actors/actor-context.ts +142 -134
- package/src/runtime/actors/actor-creation.ts +47 -44
- package/src/runtime/actors/actor-execution-context.ts +6 -4
- package/src/runtime/actors/actor-handoff.ts +269 -293
- package/src/runtime/actors/actor-join-deferred-scope.ts +1 -32
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +5 -8
- package/src/runtime/actors/actor-local-native-join.ts +131 -159
- package/src/runtime/actors/actor-mailbox.ts +16 -19
- package/src/runtime/actors/actor-message-follow-context.ts +46 -36
- package/src/runtime/actors/actor-packet-relay-wire.ts +32 -21
- package/src/runtime/actors/actor-remote-joiner.ts +50 -54
- package/src/runtime/actors/actor-remote-wire.ts +9 -13
- package/src/runtime/actors/actor-routed-join-transport.ts +10 -2
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -5
- package/src/runtime/actors/actor-runtime-state.ts +127 -124
- package/src/runtime/actors/actor-transfer-registry.ts +9 -14
- package/src/runtime/actors/actor-transport-delivery-gate.ts +4 -6
- package/src/runtime/actors/bound-session-wire.ts +37 -17
- package/src/runtime/actors/deferred-join-accepted-journal.ts +353 -326
- package/src/runtime/actors/index.ts +43 -86
- package/src/runtime/actors/post-commit-actor-binder.ts +10 -10
- package/src/runtime/actors/post-commit-actor-location.ts +30 -23
- package/src/runtime/actors/spot-actor-dispatch.ts +78 -53
- package/src/runtime/actors/transferred-actor-rollback.ts +18 -13
- package/src/runtime/admission.ts +9 -9
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +5 -15
- package/src/runtime/application-jobs/application-job-queue-handler-start-gate.ts +3 -2
- package/src/runtime/application-jobs/receive-flow-controller.ts +17 -14
- package/src/runtime/backend/contracts/index.ts +77 -52
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -14
- package/src/runtime/backend/mesh-completion-table.ts +6 -9
- package/src/runtime/backend/mesh-dispatch-pump.ts +38 -30
- package/src/runtime/backend/node/node-backend-adapter-factory.ts +23 -21
- package/src/runtime/backend/node/node-backend-adapter-support.ts +36 -22
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +59 -58
- package/src/runtime/backend/node/node-event-loop-poller.ts +2 -10
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +12 -5
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +4 -3
- package/src/runtime/backend/node/node-raw-binding-port.ts +29 -29
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +370 -390
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +101 -54
- package/src/runtime/backend/runtime-message.ts +5 -3
- package/src/runtime/backend/runtime-values.ts +10 -7
- package/src/runtime/channels/channel-autoconnect.ts +1 -4
- package/src/runtime/channels/channel-clients.ts +93 -73
- package/src/runtime/channels/channel-dispatch-pipeline.ts +44 -44
- package/src/runtime/channels/channel-dispatch-services.ts +51 -49
- package/src/runtime/channels/channel-dispatchers.ts +152 -96
- package/src/runtime/channels/channel-envelope-inspection.ts +20 -16
- package/src/runtime/channels/channel-envelope.ts +256 -150
- package/src/runtime/channels/channel-multipart.ts +13 -5
- package/src/runtime/channels/channel-outbound-operations.ts +37 -41
- package/src/runtime/channels/channel-receive-loops.ts +102 -98
- package/src/runtime/channels/channel-receive-task-tracker.ts +1 -1
- package/src/runtime/channels/channel-runtime-lifecycle.ts +248 -190
- package/src/runtime/channels/channel-runtime-manager.ts +63 -37
- package/src/runtime/channels/channel-socket-options.ts +3 -10
- package/src/runtime/channels/channel-socket-registry.ts +331 -273
- package/src/runtime/channels/channel-transports.ts +218 -206
- package/src/runtime/channels/client-server-location-runtime.ts +116 -100
- package/src/runtime/channels/client-server-service-wire.ts +37 -36
- package/src/runtime/channels/dispatch-error-reporter.ts +12 -47
- package/src/runtime/channels/fanout-location-runtime.ts +91 -94
- package/src/runtime/channels/fanout-service-wire.ts +5 -12
- package/src/runtime/channels/handler-filter-scope.ts +1 -4
- package/src/runtime/channels/index.ts +1 -4
- package/src/runtime/channels/local-spot-route-transport.ts +20 -5
- package/src/runtime/channels/route-member-snapshot.ts +11 -5
- package/src/runtime/channels/router-socket-spot-route-transport.ts +1 -7
- package/src/runtime/channels/source-spot-router.ts +26 -22
- package/src/runtime/channels/spot-direct-envelope.ts +10 -8
- package/src/runtime/channels/spot-node-route-transport.ts +13 -16
- package/src/runtime/channels/spot-route-bridge-transport.ts +26 -9
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +40 -13
- package/src/runtime/channels/spot-route-target-resolver.ts +18 -9
- package/src/runtime/codecs/index.ts +3 -2
- package/src/runtime/diagnostics/dispatch-error-details.ts +62 -0
- package/src/runtime/diagnostics/flow-context.ts +18 -7
- package/src/runtime/diagnostics/index.ts +96 -61
- package/src/runtime/diagnostics/internal-event-contracts.ts +87 -33
- package/src/runtime/diagnostics/message-flow.ts +107 -79
- package/src/runtime/diagnostics/runtime-metrics.ts +46 -24
- package/src/runtime/diagnostics/runtime-observation-queue.ts +17 -28
- package/src/runtime/diagnostics/topology-runtime-projections.ts +62 -43
- package/src/runtime/execution/index.ts +18 -26
- package/src/runtime/execution/serial-execution-queue.ts +31 -40
- package/src/runtime/execution/state-lane.ts +2 -2
- package/src/runtime/foundation/actor-join-recovery-codec.ts +69 -55
- package/src/runtime/foundation/event-loop-resources.ts +8 -4
- package/src/runtime/foundation/message-follow-suppression-registry.ts +7 -14
- package/src/runtime/foundation/operation-identity.ts +1 -2
- package/src/runtime/foundation/operation-registry.ts +8 -2
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +364 -396
- package/src/runtime/foundation/route-mesh-connection-policy.ts +7 -8
- package/src/runtime/foundation/runtime-state-projections.ts +24 -23
- package/src/runtime/foundation/service-authority-payload-codec.ts +54 -57
- package/src/runtime/foundation/service-discovery-registry.ts +67 -59
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +28 -29
- package/src/runtime/foundation/service-liveness-registry.ts +18 -13
- package/src/runtime/foundation/service-mailbox.ts +14 -14
- package/src/runtime/foundation/service-maintenance-runtime.ts +22 -21
- package/src/runtime/foundation/service-metadata-codec.ts +2 -9
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +39 -36
- package/src/runtime/foundation/service-relocation-coordinator.ts +1 -4
- package/src/runtime/foundation/service-relocation-object-owner.ts +40 -58
- package/src/runtime/foundation/service-relocation-runtime.ts +292 -216
- package/src/runtime/foundation/service-runtime-contracts.ts +8 -8
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -4
- package/src/runtime/foundation/service-stateful-registry.ts +69 -59
- package/src/runtime/foundation/service-stateful-runtime.ts +1233 -1112
- package/src/runtime/foundation/service-stateful-wire-codec.ts +318 -270
- package/src/runtime/foundation/service-topology-registry.ts +170 -159
- package/src/runtime/foundation/service-weighted-selection.ts +9 -15
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -12
- package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -47
- package/src/runtime/framework-errors-internal.ts +31 -30
- package/src/runtime/handlers/handler-instance-scope.ts +18 -29
- package/src/runtime/handlers/index.ts +18 -8
- package/src/runtime/host/actor-packet-relay.ts +290 -261
- package/src/runtime/host/actor-placement-coordinator.ts +165 -150
- package/src/runtime/host/actor-runtime-options-factory.ts +89 -87
- package/src/runtime/host/actor-transfer-authority-runtime.ts +46 -38
- package/src/runtime/host/actor-transfer-runtime.ts +391 -395
- package/src/runtime/host/application-job-queue.ts +32 -48
- package/src/runtime/host/bound-session-relay.ts +7 -9
- package/src/runtime/host/channel-runtime-options-factory.ts +75 -35
- package/src/runtime/host/host-capacity-status.ts +10 -9
- package/src/runtime/host/index.ts +861 -789
- package/src/runtime/host/instance-activation-authority.ts +125 -143
- package/src/runtime/host/location-runtime-owner.ts +38 -26
- package/src/runtime/host/mesh-router-resolver.ts +30 -23
- package/src/runtime/host/relocation-direct-transfer.ts +15 -15
- package/src/runtime/host/relocation-integrity-fault-gate.ts +3 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +43 -34
- package/src/runtime/host/remote-actor-packet-target-store.ts +54 -52
- package/src/runtime/host/remote-bound-session-relay.ts +274 -247
- package/src/runtime/host/route-mesh-runtime-options.ts +1 -3
- package/src/runtime/host/route-mesh-runtime.ts +227 -181
- package/src/runtime/host/runtime-shutdown.ts +4 -3
- package/src/runtime/host/service-relocation-control.ts +14 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +1388 -1165
- package/src/runtime/host/spot-address-transport.ts +284 -237
- package/src/runtime/host/spot-node-runtime-options-factory.ts +14 -8
- package/src/runtime/host/spot-runtime-options-factory.ts +71 -62
- package/src/runtime/host/stateful-authority-route-runtime.ts +117 -116
- package/src/runtime/host/user-spot-creation-coordinator.ts +225 -220
- package/src/runtime/locations/actor-location-claims.ts +61 -49
- package/src/runtime/locations/actor-session-route-claims.ts +1 -4
- package/src/runtime/locations/aggregate-inventory-store.ts +105 -134
- package/src/runtime/locations/authority-key-codec.ts +13 -10
- package/src/runtime/locations/auto-connect-loop.ts +14 -11
- package/src/runtime/locations/auto-connect-planner.ts +42 -31
- package/src/runtime/locations/auto-connect-reconciler.ts +106 -63
- package/src/runtime/locations/canonical-codec.ts +3 -1
- package/src/runtime/locations/creation-operation-id.ts +4 -3
- package/src/runtime/locations/domain-store-contract.ts +13 -7
- package/src/runtime/locations/in-memory-authority-store.ts +232 -199
- package/src/runtime/locations/in-memory-location-store.ts +432 -250
- package/src/runtime/locations/in-memory-provider-location-store.ts +16 -17
- package/src/runtime/locations/internal-store-contracts.ts +95 -38
- package/src/runtime/locations/key-codec.ts +3 -4
- package/src/runtime/locations/lease-tracker.ts +36 -27
- package/src/runtime/locations/lifecycle-runtime.ts +15 -3
- package/src/runtime/locations/lifecycle.ts +33 -28
- package/src/runtime/locations/location-store-repository.ts +1329 -1185
- package/src/runtime/locations/opaque-record-key.ts +4 -9
- package/src/runtime/locations/resolvers.ts +201 -178
- package/src/runtime/locations/runtime.ts +251 -159
- package/src/runtime/locations/spot-location-claims.ts +110 -112
- package/src/runtime/messaging/creation-payload-codec.ts +4 -1
- package/src/runtime/messaging/framework-json-v1.ts +34 -15
- package/src/runtime/messaging/packet-name.ts +8 -6
- package/src/runtime/messaging/payload-codec.ts +70 -50
- package/src/runtime/messaging/submission-result.ts +6 -9
- package/src/runtime/protocol/service_wire_codec.generated.ts +1376 -159
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +19 -18
- package/src/runtime/routing-id.ts +10 -7
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +56 -62
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +23 -20
- package/src/runtime/spots/index.ts +595 -564
- package/src/runtime/spots/spot-activation-registry.ts +38 -34
- package/src/runtime/spots/spot-activation-state.ts +43 -51
- package/src/runtime/spots/spot-activation.ts +179 -116
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +110 -78
- package/src/runtime/spots/spot-actor-join-dispatch.ts +57 -41
- package/src/runtime/spots/spot-actor-lifecycle-drain.ts +5 -7
- package/src/runtime/spots/spot-actor-membership.ts +25 -27
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +196 -148
- package/src/runtime/spots/spot-actor-packet-drain.ts +56 -42
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +37 -39
- package/src/runtime/spots/spot-closing.ts +11 -12
- package/src/runtime/spots/spot-context.ts +46 -26
- package/src/runtime/spots/spot-entry-activation.ts +84 -65
- package/src/runtime/spots/spot-handle.ts +17 -15
- package/src/runtime/spots/spot-handler-registry.ts +44 -31
- package/src/runtime/spots/spot-location-claim.ts +5 -4
- package/src/runtime/spots/spot-manager-public.ts +62 -82
- package/src/runtime/spots/spot-native-actor-join-admission.ts +20 -16
- package/src/runtime/spots/spot-node-autoconnect.ts +54 -61
- package/src/runtime/spots/spot-node-runtime-manager.ts +235 -222
- package/src/runtime/spots/spot-outbound.ts +47 -59
- package/src/runtime/spots/spot-publisher-transport.ts +5 -4
- package/src/runtime/spots/spot-remote-codec.ts +66 -65
- package/src/runtime/spots/spot-remote-route-codec.ts +61 -41
- package/src/runtime/spots/spot-route-packet-dispatch.ts +129 -95
- package/src/runtime/spots/spot-route-replies.ts +23 -24
- package/src/runtime/spots/spot-route-reply-wire.ts +3 -2
- package/src/runtime/spots/spot-routed-actor-admission.ts +37 -27
- package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +13 -18
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +18 -15
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +35 -26
- package/src/runtime/spots/spot-routing-internal.ts +1 -4
- package/src/runtime/spots/spot-runtime-ports.ts +5 -5
- package/src/runtime/spots/spot-serial-executor.ts +5 -9
- package/src/runtime/spots/spot-serial-turn-executor.ts +19 -26
- package/src/runtime/spots/spot-subscription-dispatch.ts +58 -47
- package/src/runtime/spots/spot-timer.ts +103 -91
- package/src/runtime/streams/actor-session-binding-registry.ts +421 -292
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +8 -4
- package/src/runtime/streams/actor-session-lifecycle-coordinator.ts +3 -1
- package/src/runtime/streams/bound-actor-relay-sender.ts +60 -50
- package/src/runtime/streams/bound-session-response-target.ts +39 -9
- package/src/runtime/streams/bound-session-service.ts +52 -42
- package/src/runtime/streams/index.ts +183 -100
- package/src/runtime/streams/managed-stream.ts +123 -90
- package/src/runtime/streams/native-fallback-bound-session.ts +57 -52
- package/src/runtime/streams/protocol.ts +115 -46
- package/src/runtime/streams/session-actor-coordinator.ts +109 -93
- package/src/runtime/streams/session-calls.ts +2 -8
- package/src/runtime/streams/session-context.ts +96 -51
- package/src/runtime/streams/session-local-actors.ts +19 -3
- package/src/runtime/streams/session-provider.ts +5 -7
- package/src/runtime/streams/session-serial-executor.ts +7 -6
- package/src/runtime/streams/stream-binding-runtime-ports.ts +79 -29
- package/src/runtime/streams/stream-frame-factory.ts +59 -40
- package/src/runtime/streams/stream-session-runtime.ts +317 -214
- package/src/runtime/workers/index.ts +68 -29
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { randomBytes } from 'node:crypto';
|
|
2
2
|
import { setImmediate as yieldToIO } from 'node:timers/promises';
|
|
3
|
+
import {
|
|
4
|
+
decodeStreamWireFrame,
|
|
5
|
+
decodeStreamWireHeader,
|
|
6
|
+
encodeStreamWireFrame,
|
|
7
|
+
encodeStreamWireHeader
|
|
8
|
+
} from '@zlink-systems/stream-wire';
|
|
3
9
|
import { disconnectStreamPeer } from './node-socket-backend-adapter';
|
|
4
10
|
import { ZLinkFrameworkException } from '../../../contracts';
|
|
5
11
|
import { internalFrameworkWireReply } from '../../framework-errors-internal';
|
|
@@ -20,6 +26,7 @@ import {
|
|
|
20
26
|
} from '../runtime-values';
|
|
21
27
|
import { ZLinkBufferMessage } from '../runtime-message';
|
|
22
28
|
import type { Message as FrameworkMessage } from '../../../contracts/Common/Message';
|
|
29
|
+
import type { ZLinkDispatchErrorReporter } from '../../channels/dispatch-error-reporter';
|
|
23
30
|
import type {
|
|
24
31
|
MeshOperationId,
|
|
25
32
|
MeshPeerEntry,
|
|
@@ -70,12 +77,8 @@ import {
|
|
|
70
77
|
type ServiceStatefulPendingOperation,
|
|
71
78
|
type ServiceStatefulResult
|
|
72
79
|
} from '../../foundation/service-stateful-runtime';
|
|
73
|
-
import type {
|
|
74
|
-
|
|
75
|
-
ServiceSpotState
|
|
76
|
-
} from '../../foundation/service-stateful-registry';
|
|
77
|
-
import { serviceSessionBindingIngressPortIfRegistered } from
|
|
78
|
-
'../../foundation/service-session-binding-ingress-port';
|
|
80
|
+
import type { ServiceActorRef, ServiceSpotState } from '../../foundation/service-stateful-registry';
|
|
81
|
+
import { serviceSessionBindingIngressPortIfRegistered } from '../../foundation/service-session-binding-ingress-port';
|
|
79
82
|
import type {
|
|
80
83
|
ServiceActorCreateRecord,
|
|
81
84
|
ServiceDirectSpotRouteFence,
|
|
@@ -87,9 +90,7 @@ import type {
|
|
|
87
90
|
ServiceUserSpotCreateRecord
|
|
88
91
|
} from '../../foundation/service-stateful-wire-codec';
|
|
89
92
|
import { encodeServiceMetadataFrame } from '../../foundation/service-metadata-codec';
|
|
90
|
-
import type {
|
|
91
|
-
ServiceInstanceActivationRecoveryEnvelope
|
|
92
|
-
} from '../../foundation/service-instance-activation-recovery-codec';
|
|
93
|
+
import type { ServiceInstanceActivationRecoveryEnvelope } from '../../foundation/service-instance-activation-recovery-codec';
|
|
93
94
|
import type {
|
|
94
95
|
ServiceMailboxClaim,
|
|
95
96
|
ServiceMailboxDomain,
|
|
@@ -101,8 +102,7 @@ import type {
|
|
|
101
102
|
} from '../../foundation/service-topology-registry';
|
|
102
103
|
import type { RoutingId } from '../../../contracts';
|
|
103
104
|
import { buildAdvertisedEndpoint } from '../../../contracts/Configuration/EndpointNotation';
|
|
104
|
-
import { ZLinkConfigurationException } from
|
|
105
|
-
'../../../contracts/Configuration/ConfigurationException';
|
|
105
|
+
import { ZLinkConfigurationException } from '../../../contracts/Configuration/ConfigurationException';
|
|
106
106
|
import type {
|
|
107
107
|
ZLinkBackendActorRef,
|
|
108
108
|
ZLinkBackendActorSessionSendFence,
|
|
@@ -135,11 +135,14 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
135
135
|
readonly nativeInstance = this;
|
|
136
136
|
|
|
137
137
|
private readonly channels = new Map<string, number>();
|
|
138
|
-
private readonly peerIntents = new Map<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
private readonly peerIntents = new Map<
|
|
139
|
+
bigint,
|
|
140
|
+
{
|
|
141
|
+
readonly endpoint: string;
|
|
142
|
+
readonly nodeRoutingId?: string;
|
|
143
|
+
readonly lifecycleGeneration?: bigint;
|
|
144
|
+
}
|
|
145
|
+
>();
|
|
143
146
|
private readonly completions: Array<PendingCompletion | undefined> = [];
|
|
144
147
|
private completionHead = 0;
|
|
145
148
|
private completionCount = 0;
|
|
@@ -182,6 +185,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
182
185
|
private messageFollowHandler?: (
|
|
183
186
|
record: import('../../foundation/service-stateful-wire-codec').ServiceMessageFollowRecord
|
|
184
187
|
) => void;
|
|
188
|
+
private dispatchErrors?: ZLinkDispatchErrorReporter;
|
|
185
189
|
private readonly peerDisconnectedHandlers = new Set<(endpoint: string) => void>();
|
|
186
190
|
constructor(
|
|
187
191
|
private readonly meshName: string,
|
|
@@ -209,10 +213,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
209
213
|
}): void {
|
|
210
214
|
this.requireNotStarted();
|
|
211
215
|
this.objectRole = options.role;
|
|
212
|
-
this.placementWeight = requirePublicWeight(
|
|
213
|
-
options.placementWeight,
|
|
214
|
-
'placementWeight'
|
|
215
|
-
);
|
|
216
|
+
this.placementWeight = requirePublicWeight(options.placementWeight, 'placementWeight');
|
|
216
217
|
this.activeCapacityLimit = requirePositivePlacementValue(
|
|
217
218
|
options.activeCapacityLimit,
|
|
218
219
|
'activeCapacityLimit'
|
|
@@ -225,20 +226,29 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
225
226
|
this.maintenanceWave = options.maintenanceWave;
|
|
226
227
|
}
|
|
227
228
|
|
|
228
|
-
setMailboxRecordDroppedHandler(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
229
|
+
setMailboxRecordDroppedHandler(
|
|
230
|
+
handler: (record: {
|
|
231
|
+
readonly kind: 'spot_multicast' | 'actor_control' | 'actor_binding';
|
|
232
|
+
readonly owner: string;
|
|
233
|
+
}) => void
|
|
234
|
+
): void {
|
|
232
235
|
this.mailboxRecordDropped = handler;
|
|
233
236
|
this.stateful?.setMailboxDropHandler(handler);
|
|
234
237
|
}
|
|
235
238
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
239
|
+
setDispatchErrorReporter(reporter: ZLinkDispatchErrorReporter): void {
|
|
240
|
+
this.dispatchErrors = reporter;
|
|
241
|
+
this.stateful?.setDispatchErrorReporter(reporter, this.meshName);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
setProtocolErrorHandler(
|
|
245
|
+
handler: (record: {
|
|
246
|
+
readonly sourceNodeRid: string;
|
|
247
|
+
readonly request: boolean;
|
|
248
|
+
readonly replied: boolean;
|
|
249
|
+
readonly command?: number;
|
|
250
|
+
}) => void
|
|
251
|
+
): void {
|
|
242
252
|
this.protocolError = handler;
|
|
243
253
|
}
|
|
244
254
|
|
|
@@ -251,14 +261,16 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
251
261
|
const localNodeRid = runtime.topology.localDescriptor().nodeRoutingId;
|
|
252
262
|
const status = runtime.topology.objectPlacementStatus(
|
|
253
263
|
stableType,
|
|
254
|
-
candidate =>
|
|
255
|
-
|
|
264
|
+
(candidate) =>
|
|
265
|
+
candidate.nodeRoutingId === localNodeRid ||
|
|
266
|
+
runtime.isPeerRouteReady(candidate.nodeRoutingId)
|
|
256
267
|
);
|
|
257
268
|
if (status !== 'available') return { kind: status };
|
|
258
269
|
const descriptor = runtime.topology.selectObjectPlacement(
|
|
259
270
|
stableType,
|
|
260
|
-
candidate =>
|
|
261
|
-
|
|
271
|
+
(candidate) =>
|
|
272
|
+
candidate.nodeRoutingId === localNodeRid ||
|
|
273
|
+
runtime.isPeerRouteReady(candidate.nodeRoutingId)
|
|
262
274
|
);
|
|
263
275
|
return descriptor === undefined
|
|
264
276
|
? { kind: 'unavailable' }
|
|
@@ -333,33 +345,32 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
333
345
|
start(): void {
|
|
334
346
|
if (this.runtime !== undefined) return;
|
|
335
347
|
if (this.closed) throw new Error('MeshNode is closed.');
|
|
336
|
-
if (this.bindEndpoint === undefined)
|
|
348
|
+
if (this.bindEndpoint === undefined)
|
|
349
|
+
throw new Error('MeshNode bind endpoint is not configured.');
|
|
337
350
|
const descriptor = this.createDescriptor();
|
|
338
351
|
const runtime = new RawServiceMeshRuntime({
|
|
339
352
|
descriptor,
|
|
340
|
-
resolveAdvertisedEndpoint: boundEndpoint =>
|
|
341
|
-
this.resolveAdvertisedEndpoint(boundEndpoint),
|
|
353
|
+
resolveAdvertisedEndpoint: (boundEndpoint) => this.resolveAdvertisedEndpoint(boundEndpoint),
|
|
342
354
|
bindingPort: this.bindingPort,
|
|
343
355
|
applicationJobQueue: this.requireApplicationJobQueue(),
|
|
344
356
|
peerAdmissionSealed: this.peerAdmissionSealed,
|
|
345
357
|
onReceiveFlowConfigFailure: this.applicationJobReceiveFlowFailureSink,
|
|
346
|
-
onMailboxReady: (domain) =>
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
358
|
+
onMailboxReady: (domain) =>
|
|
359
|
+
this.readyHandler?.(
|
|
360
|
+
domain === 'application' ? ReadyDomain.Application : ReadyDomain.Infrastructure
|
|
361
|
+
),
|
|
362
|
+
onProtocolError: (record) =>
|
|
363
|
+
this.protocolError?.({
|
|
364
|
+
sourceNodeRid: record.sourceRoutingId,
|
|
365
|
+
request: record.request,
|
|
366
|
+
replied: record.replied,
|
|
367
|
+
...(record.command === undefined ? {} : { command: record.command })
|
|
368
|
+
}),
|
|
355
369
|
onPeerNotRequired: (nodeRoutingId, endpoint) => {
|
|
356
370
|
for (const [intent, peer] of this.peerIntents) {
|
|
357
371
|
if (
|
|
358
|
-
(
|
|
359
|
-
|
|
360
|
-
|| peer.nodeRoutingId === nodeRoutingId
|
|
361
|
-
)
|
|
362
|
-
&& peer.endpoint === endpoint
|
|
372
|
+
(peer.nodeRoutingId === undefined || peer.nodeRoutingId === nodeRoutingId) &&
|
|
373
|
+
peer.endpoint === endpoint
|
|
363
374
|
) {
|
|
364
375
|
this.peerIntents.delete(intent);
|
|
365
376
|
}
|
|
@@ -368,8 +379,8 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
368
379
|
onPeerDisconnected: (nodeRoutingId, endpoint) => {
|
|
369
380
|
for (const [intentId, peer] of this.peerIntents) {
|
|
370
381
|
if (
|
|
371
|
-
peer.endpoint === endpoint
|
|
372
|
-
|
|
382
|
+
peer.endpoint === endpoint &&
|
|
383
|
+
(peer.nodeRoutingId === undefined || peer.nodeRoutingId === nodeRoutingId)
|
|
373
384
|
) {
|
|
374
385
|
this.peerIntents.delete(intentId);
|
|
375
386
|
}
|
|
@@ -383,6 +394,9 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
383
394
|
descriptor.nodeRoutingId,
|
|
384
395
|
descriptor.lifecycleGeneration
|
|
385
396
|
);
|
|
397
|
+
if (this.dispatchErrors !== undefined) {
|
|
398
|
+
this.stateful.setDispatchErrorReporter(this.dispatchErrors, this.meshName);
|
|
399
|
+
}
|
|
386
400
|
if (this.mailboxRecordDropped !== undefined) {
|
|
387
401
|
this.stateful.setMailboxDropHandler(this.mailboxRecordDropped);
|
|
388
402
|
}
|
|
@@ -397,9 +411,11 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
397
411
|
this.scheduleMaintenance();
|
|
398
412
|
}
|
|
399
413
|
|
|
400
|
-
setMessageFollowHandler(
|
|
401
|
-
|
|
402
|
-
|
|
414
|
+
setMessageFollowHandler(
|
|
415
|
+
handler: (
|
|
416
|
+
record: import('../../foundation/service-stateful-wire-codec').ServiceMessageFollowRecord
|
|
417
|
+
) => void
|
|
418
|
+
): void {
|
|
403
419
|
this.messageFollowHandler = handler;
|
|
404
420
|
}
|
|
405
421
|
|
|
@@ -470,27 +486,27 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
470
486
|
readonly expectedLifecycleGeneration?: bigint;
|
|
471
487
|
}): Promise<bigint> {
|
|
472
488
|
const runtime = this.requireRuntime();
|
|
473
|
-
const nodeRoutingId =
|
|
474
|
-
? undefined
|
|
475
|
-
: String(options.expectedRid);
|
|
489
|
+
const nodeRoutingId =
|
|
490
|
+
options.expectedRid === undefined ? undefined : String(options.expectedRid);
|
|
476
491
|
if (nodeRoutingId === undefined) {
|
|
477
492
|
runtime.connectPeerEndpoint(options.endpoint);
|
|
478
493
|
} else {
|
|
479
494
|
runtime.connectPeerByRoutingId(
|
|
480
495
|
options.endpoint,
|
|
481
496
|
nodeRoutingId,
|
|
482
|
-
options.expectedSecurityIdentity
|
|
483
|
-
?? runtime.topology.localDescriptor().securityIdentity,
|
|
497
|
+
options.expectedSecurityIdentity ?? runtime.topology.localDescriptor().securityIdentity,
|
|
484
498
|
options.expectedLifecycleGeneration
|
|
485
499
|
);
|
|
486
500
|
}
|
|
487
501
|
const intent = this.nextPeerIntent++;
|
|
488
502
|
this.peerIntents.set(intent, {
|
|
489
503
|
endpoint: options.endpoint,
|
|
490
|
-
...(nodeRoutingId === undefined
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
504
|
+
...(nodeRoutingId === undefined
|
|
505
|
+
? {}
|
|
506
|
+
: {
|
|
507
|
+
nodeRoutingId,
|
|
508
|
+
lifecycleGeneration: options.expectedLifecycleGeneration
|
|
509
|
+
})
|
|
494
510
|
});
|
|
495
511
|
if (nodeRoutingId !== undefined) await runtime.announcePeer(nodeRoutingId);
|
|
496
512
|
return intent;
|
|
@@ -528,27 +544,19 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
528
544
|
disconnectPeer(peerRid: unknown, lifecycleGeneration: bigint): void {
|
|
529
545
|
const nodeRoutingId = String(peerRid);
|
|
530
546
|
const admitted = this.runtime?.topology.peer(nodeRoutingId);
|
|
531
|
-
if (
|
|
532
|
-
admitted !== undefined
|
|
533
|
-
&& admitted.descriptor.lifecycleGeneration !== lifecycleGeneration
|
|
534
|
-
) {
|
|
547
|
+
if (admitted !== undefined && admitted.descriptor.lifecycleGeneration !== lifecycleGeneration) {
|
|
535
548
|
return;
|
|
536
549
|
}
|
|
537
550
|
const admittedEndpoint = admitted?.descriptor.advertisedEndpoint;
|
|
538
|
-
const found = [...this.peerIntents.entries()]
|
|
539
|
-
|
|
540
|
-
(
|
|
541
|
-
intent.
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
)
|
|
546
|
-
|
|
547
|
-
|| (
|
|
548
|
-
intent.nodeRoutingId === undefined
|
|
549
|
-
&& admittedEndpoint !== undefined
|
|
550
|
-
&& intent.endpoint === admittedEndpoint
|
|
551
|
-
));
|
|
551
|
+
const found = [...this.peerIntents.entries()].find(
|
|
552
|
+
([, intent]) =>
|
|
553
|
+
(intent.nodeRoutingId === nodeRoutingId &&
|
|
554
|
+
(intent.lifecycleGeneration === undefined ||
|
|
555
|
+
intent.lifecycleGeneration === lifecycleGeneration)) ||
|
|
556
|
+
(intent.nodeRoutingId === undefined &&
|
|
557
|
+
admittedEndpoint !== undefined &&
|
|
558
|
+
intent.endpoint === admittedEndpoint)
|
|
559
|
+
);
|
|
552
560
|
if (found === undefined) {
|
|
553
561
|
if (admitted !== undefined) {
|
|
554
562
|
this.runtime?.disconnectPeer(
|
|
@@ -562,22 +570,26 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
562
570
|
this.removePeerConnection(found[0]);
|
|
563
571
|
}
|
|
564
572
|
|
|
565
|
-
replaceDiscoveredNotRequiredPeers(
|
|
566
|
-
readonly
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
573
|
+
replaceDiscoveredNotRequiredPeers(
|
|
574
|
+
peers: readonly {
|
|
575
|
+
readonly nodeRoutingId: string;
|
|
576
|
+
readonly lifecycleGeneration: bigint;
|
|
577
|
+
readonly descriptorRevision: bigint;
|
|
578
|
+
readonly endpoint: string;
|
|
579
|
+
}[]
|
|
580
|
+
): void {
|
|
571
581
|
const local = this.requireRuntime().topology.localDescriptor();
|
|
572
|
-
this.requireRuntime().replaceDiscoveredNotRequired(
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
582
|
+
this.requireRuntime().replaceDiscoveredNotRequired(
|
|
583
|
+
peers.map((peer) => ({
|
|
584
|
+
...local,
|
|
585
|
+
nodeRoutingId: peer.nodeRoutingId,
|
|
586
|
+
lifecycleGeneration: peer.lifecycleGeneration,
|
|
587
|
+
descriptorRevision: peer.descriptorRevision,
|
|
588
|
+
advertisedEndpoint: peer.endpoint,
|
|
589
|
+
channels: [],
|
|
590
|
+
objectRole: 'client'
|
|
591
|
+
}))
|
|
592
|
+
);
|
|
581
593
|
}
|
|
582
594
|
|
|
583
595
|
isObjectClientNodeDirectTarget(targetRid: unknown): boolean {
|
|
@@ -592,30 +604,36 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
592
604
|
targetRid: unknown,
|
|
593
605
|
parts: MessageLike | readonly MessageLike[]
|
|
594
606
|
): Promise<SubmitResultValue> {
|
|
595
|
-
return await this.requireRuntime().sendToNode(
|
|
607
|
+
return (await this.requireRuntime().sendToNode(
|
|
596
608
|
String(targetRid),
|
|
597
609
|
encodeMultipartApplicationFrame(parts)
|
|
598
|
-
)
|
|
610
|
+
))
|
|
611
|
+
? SubmitResult.Ok
|
|
612
|
+
: SubmitResult.NotConnected;
|
|
599
613
|
}
|
|
600
614
|
|
|
601
615
|
async sendInfrastructureControl(
|
|
602
616
|
targetRid: unknown,
|
|
603
617
|
record: Uint8Array | readonly Uint8Array[]
|
|
604
618
|
): Promise<SubmitResultValue> {
|
|
605
|
-
return await this.requireRuntime().sendService(
|
|
619
|
+
return (await this.requireRuntime().sendService(
|
|
606
620
|
String(targetRid),
|
|
607
|
-
(Array.isArray(record) ? record : [record]).map(value => Buffer.from(value))
|
|
608
|
-
)
|
|
621
|
+
(Array.isArray(record) ? record : [record]).map((value) => Buffer.from(value))
|
|
622
|
+
))
|
|
623
|
+
? SubmitResult.Ok
|
|
624
|
+
: SubmitResult.NotConnected;
|
|
609
625
|
}
|
|
610
626
|
|
|
611
627
|
async sendInfrastructureControlFrames(
|
|
612
628
|
targetRid: unknown,
|
|
613
629
|
frames: readonly Uint8Array[]
|
|
614
630
|
): Promise<SubmitResultValue> {
|
|
615
|
-
return await this.requireRuntime().sendService(
|
|
631
|
+
return (await this.requireRuntime().sendService(
|
|
616
632
|
String(targetRid),
|
|
617
|
-
frames.map(frame => Buffer.from(frame))
|
|
618
|
-
)
|
|
633
|
+
frames.map((frame) => Buffer.from(frame))
|
|
634
|
+
))
|
|
635
|
+
? SubmitResult.Ok
|
|
636
|
+
: SubmitResult.NotConnected;
|
|
619
637
|
}
|
|
620
638
|
|
|
621
639
|
async requestInfrastructureControlFrames(
|
|
@@ -625,7 +643,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
625
643
|
): Promise<readonly Uint8Array[]> {
|
|
626
644
|
return await this.requireRuntime().requestService(
|
|
627
645
|
String(targetRid),
|
|
628
|
-
frames.map(frame => Buffer.from(frame)),
|
|
646
|
+
frames.map((frame) => Buffer.from(frame)),
|
|
629
647
|
options?.timeoutMs ?? 30_000
|
|
630
648
|
);
|
|
631
649
|
}
|
|
@@ -647,10 +665,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
647
665
|
channelName: string,
|
|
648
666
|
parts: MessageLike | readonly MessageLike[]
|
|
649
667
|
): Promise<SubmitResultValue> {
|
|
650
|
-
return
|
|
651
|
-
channelName,
|
|
652
|
-
encodeMultipartApplicationFrame(parts)
|
|
653
|
-
) ? SubmitResult.Ok : SubmitResult.NotConnected;
|
|
668
|
+
return this.requireRuntime().sendToChannel(channelName, encodeMultipartApplicationFrame(parts));
|
|
654
669
|
}
|
|
655
670
|
|
|
656
671
|
requestToChannel(
|
|
@@ -663,9 +678,6 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
663
678
|
encodeMultipartApplicationFrame(parts),
|
|
664
679
|
options?.timeoutMs ?? 30_000
|
|
665
680
|
);
|
|
666
|
-
if (pending === undefined) {
|
|
667
|
-
return this.enqueueImmediateFailure(OperationKind.ChannelRequest, RequestResult.NotFound);
|
|
668
|
-
}
|
|
669
681
|
return this.observeCompletion(pending.id, OperationKind.ChannelRequest, pending.promise);
|
|
670
682
|
}
|
|
671
683
|
|
|
@@ -682,14 +694,14 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
682
694
|
channelCount: descriptor.channels.length,
|
|
683
695
|
configuredPeerCount: this.peerIntents.size,
|
|
684
696
|
admittedPeerCount: peers.length,
|
|
685
|
-
drainingPeerCount: peers.filter(peer => peer.descriptor.state === 'draining').length,
|
|
697
|
+
drainingPeerCount: peers.filter((peer) => peer.descriptor.state === 'draining').length,
|
|
686
698
|
pendingApplicationMessages: BigInt(this.runtime?.mailbox.pendingMessages('application') ?? 0),
|
|
687
699
|
pendingInfrastructureMessages: BigInt(
|
|
688
700
|
(this.runtime?.mailbox.pendingMessages('infrastructure') ?? 0) + this.completionCount
|
|
689
701
|
),
|
|
690
702
|
pendingBytes: BigInt(
|
|
691
|
-
(this.runtime?.mailbox.pendingBytes('application') ?? 0)
|
|
692
|
-
|
|
703
|
+
(this.runtime?.mailbox.pendingBytes('application') ?? 0) +
|
|
704
|
+
(this.runtime?.mailbox.pendingBytes('infrastructure') ?? 0)
|
|
693
705
|
),
|
|
694
706
|
lastError: 0,
|
|
695
707
|
lastChangedMs: BigInt(Math.trunc(performance.now()))
|
|
@@ -702,21 +714,19 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
702
714
|
...intent
|
|
703
715
|
}));
|
|
704
716
|
const findIntent = (nodeRoutingId: string, endpoint: string) =>
|
|
705
|
-
intents.find(
|
|
706
|
-
intent
|
|
707
|
-
|
|
708
|
-
intent.nodeRoutingId === undefined
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
peer.descriptor.nodeRoutingId,
|
|
714
|
-
peer.descriptor.advertisedEndpoint
|
|
715
|
-
)?.id ?? 0n,
|
|
717
|
+
intents.find(
|
|
718
|
+
(intent) =>
|
|
719
|
+
intent.nodeRoutingId === nodeRoutingId ||
|
|
720
|
+
(intent.nodeRoutingId === undefined && intent.endpoint === endpoint)
|
|
721
|
+
);
|
|
722
|
+
const admitted = (this.runtime?.topology.peers() ?? []).map((peer) => ({
|
|
723
|
+
connectionIntentId:
|
|
724
|
+
findIntent(peer.descriptor.nodeRoutingId, peer.descriptor.advertisedEndpoint)?.id ?? 0n,
|
|
716
725
|
source: 1,
|
|
717
|
-
state:
|
|
718
|
-
|
|
719
|
-
|
|
726
|
+
state:
|
|
727
|
+
this.runtime?.isPeerRouteReady(peer.descriptor.nodeRoutingId) === false
|
|
728
|
+
? 1
|
|
729
|
+
: peerStateCode(peer.descriptor.state),
|
|
720
730
|
routingId: peer.descriptor.nodeRoutingId as RoutingId,
|
|
721
731
|
lifecycleGeneration: peer.descriptor.lifecycleGeneration,
|
|
722
732
|
descriptorRevision: peer.descriptor.descriptorRevision,
|
|
@@ -725,11 +735,9 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
725
735
|
lastError: 0,
|
|
726
736
|
lastChangedMs: BigInt(Math.trunc(performance.now()))
|
|
727
737
|
}));
|
|
728
|
-
const notRequired = (this.runtime?.topology.notRequiredPeers() ?? []).map(descriptor => ({
|
|
729
|
-
connectionIntentId:
|
|
730
|
-
descriptor.nodeRoutingId,
|
|
731
|
-
descriptor.advertisedEndpoint
|
|
732
|
-
)?.id ?? 0n,
|
|
738
|
+
const notRequired = (this.runtime?.topology.notRequiredPeers() ?? []).map((descriptor) => ({
|
|
739
|
+
connectionIntentId:
|
|
740
|
+
findIntent(descriptor.nodeRoutingId, descriptor.advertisedEndpoint)?.id ?? 0n,
|
|
733
741
|
source: 1,
|
|
734
742
|
state: 6,
|
|
735
743
|
routingId: descriptor.nodeRoutingId as RoutingId,
|
|
@@ -741,14 +749,12 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
741
749
|
lastChangedMs: BigInt(Math.trunc(performance.now()))
|
|
742
750
|
}));
|
|
743
751
|
const projected = new Set([
|
|
744
|
-
...admitted.map(peer => peer.connectionIntentId),
|
|
745
|
-
...notRequired.map(peer => peer.connectionIntentId)
|
|
752
|
+
...admitted.map((peer) => peer.connectionIntentId),
|
|
753
|
+
...notRequired.map((peer) => peer.connectionIntentId)
|
|
746
754
|
]);
|
|
747
755
|
const disconnected = intents
|
|
748
|
-
.filter(intent =>
|
|
749
|
-
|
|
750
|
-
&& !projected.has(intent.id))
|
|
751
|
-
.map(intent => {
|
|
756
|
+
.filter((intent) => intent.nodeRoutingId !== undefined && !projected.has(intent.id))
|
|
757
|
+
.map((intent) => {
|
|
752
758
|
const descriptor = this.runtime?.topology.knownDescriptor(intent.nodeRoutingId!);
|
|
753
759
|
return {
|
|
754
760
|
connectionIntentId: intent.id,
|
|
@@ -765,8 +771,9 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
765
771
|
lastChangedMs: BigInt(Math.trunc(performance.now()))
|
|
766
772
|
};
|
|
767
773
|
});
|
|
768
|
-
return [...admitted, ...notRequired, ...disconnected]
|
|
769
|
-
|
|
774
|
+
return [...admitted, ...notRequired, ...disconnected].sort((left, right) =>
|
|
775
|
+
String(left.routingId).localeCompare(String(right.routingId))
|
|
776
|
+
);
|
|
770
777
|
}
|
|
771
778
|
|
|
772
779
|
peerChannels(peerRid: unknown, lifecycleGeneration: bigint) {
|
|
@@ -775,8 +782,8 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
775
782
|
return { names: [], weights: [] };
|
|
776
783
|
}
|
|
777
784
|
return {
|
|
778
|
-
names: descriptor.channels.map(channel => channel.name),
|
|
779
|
-
weights: descriptor.channels.map(channel => channel.weight)
|
|
785
|
+
names: descriptor.channels.map((channel) => channel.name),
|
|
786
|
+
weights: descriptor.channels.map((channel) => channel.weight)
|
|
780
787
|
};
|
|
781
788
|
}
|
|
782
789
|
|
|
@@ -815,17 +822,18 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
815
822
|
return new RawReadyBatch(capacity);
|
|
816
823
|
}
|
|
817
824
|
|
|
818
|
-
createReceiveBatch(
|
|
819
|
-
messageCapacity: number,
|
|
820
|
-
partCapacity: number
|
|
821
|
-
): ReceiveBatch {
|
|
825
|
+
createReceiveBatch(messageCapacity: number, partCapacity: number): ReceiveBatch {
|
|
822
826
|
return new RawReceiveBatch(messageCapacity, partCapacity);
|
|
823
827
|
}
|
|
824
828
|
|
|
825
829
|
drainReady(
|
|
826
830
|
domains: number,
|
|
827
831
|
batch: ReadyBatch
|
|
828
|
-
): {
|
|
832
|
+
): {
|
|
833
|
+
readonly ok: boolean;
|
|
834
|
+
readonly hasResidue: boolean;
|
|
835
|
+
readonly records: readonly ReadyRecord[];
|
|
836
|
+
} {
|
|
829
837
|
const target = requireRawReadyBatch(batch);
|
|
830
838
|
if ((domains & ReadyDomain.Infrastructure) !== 0) {
|
|
831
839
|
this.drainCompletions(target);
|
|
@@ -835,13 +843,12 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
835
843
|
this.drainMailbox('application', target);
|
|
836
844
|
}
|
|
837
845
|
const runtime = this.runtime;
|
|
838
|
-
const infrastructureResidue =
|
|
839
|
-
&&
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
)
|
|
843
|
-
|
|
844
|
-
&& (runtime?.mailbox.pendingMessages('application') ?? 0) > 0;
|
|
846
|
+
const infrastructureResidue =
|
|
847
|
+
(domains & ReadyDomain.Infrastructure) !== 0 &&
|
|
848
|
+
(this.completionCount > 0 || (runtime?.mailbox.pendingMessages('infrastructure') ?? 0) > 0);
|
|
849
|
+
const applicationResidue =
|
|
850
|
+
(domains & ReadyDomain.Application) !== 0 &&
|
|
851
|
+
(runtime?.mailbox.pendingMessages('application') ?? 0) > 0;
|
|
845
852
|
return {
|
|
846
853
|
ok: true,
|
|
847
854
|
// Residue is scoped to the requested lane. The pump drains lanes in
|
|
@@ -873,10 +880,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
873
880
|
return this.requireStateful().instanceSpotApplicationTarget(spotId);
|
|
874
881
|
}
|
|
875
882
|
|
|
876
|
-
waitForInstanceApplicationQuiescence(
|
|
877
|
-
spotId: string,
|
|
878
|
-
signal?: AbortSignal
|
|
879
|
-
): Promise<void> {
|
|
883
|
+
waitForInstanceApplicationQuiescence(spotId: string, signal?: AbortSignal): Promise<void> {
|
|
880
884
|
return this.requireStateful().waitForInstanceApplicationQuiescence(spotId, signal);
|
|
881
885
|
}
|
|
882
886
|
|
|
@@ -980,9 +984,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
980
984
|
this.requireStateful().registerAsyncInstanceActivationAuthority(authority);
|
|
981
985
|
}
|
|
982
986
|
|
|
983
|
-
registerInstanceApplicationLifecycle(
|
|
984
|
-
lifecycle: ServiceInstanceApplicationLifecycle
|
|
985
|
-
): void {
|
|
987
|
+
registerInstanceApplicationLifecycle(lifecycle: ServiceInstanceApplicationLifecycle): void {
|
|
986
988
|
this.requireStateful().registerInstanceApplicationLifecycle(lifecycle);
|
|
987
989
|
}
|
|
988
990
|
|
|
@@ -1027,7 +1029,11 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1027
1029
|
pending: ServicePendingInstanceActivation,
|
|
1028
1030
|
expectedCurrentRoute?: ServiceInstanceRouteFence | null
|
|
1029
1031
|
): Promise<boolean> {
|
|
1030
|
-
return this.requireStateful().recoverPendingInstanceActivation(
|
|
1032
|
+
return this.requireStateful().recoverPendingInstanceActivation(
|
|
1033
|
+
envelope,
|
|
1034
|
+
pending,
|
|
1035
|
+
expectedCurrentRoute
|
|
1036
|
+
);
|
|
1031
1037
|
}
|
|
1032
1038
|
|
|
1033
1039
|
completeRecoveredInstanceActivation(
|
|
@@ -1035,7 +1041,11 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1035
1041
|
route: ServiceInstanceRouteFence,
|
|
1036
1042
|
expectedCurrentRoute?: ServiceInstanceRouteFence | null
|
|
1037
1043
|
): Promise<ServiceInstanceRouteFence | undefined> {
|
|
1038
|
-
return this.requireStateful().completeRecoveredInstanceActivation(
|
|
1044
|
+
return this.requireStateful().completeRecoveredInstanceActivation(
|
|
1045
|
+
target,
|
|
1046
|
+
route,
|
|
1047
|
+
expectedCurrentRoute
|
|
1048
|
+
);
|
|
1039
1049
|
}
|
|
1040
1050
|
|
|
1041
1051
|
forgetInstanceIntent(
|
|
@@ -1059,10 +1069,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1059
1069
|
this.requireStateful().rememberSpotRoute(route, expectedCurrentRoute);
|
|
1060
1070
|
}
|
|
1061
1071
|
|
|
1062
|
-
entrySpotRouteFence(
|
|
1063
|
-
targetNodeRid: string,
|
|
1064
|
-
targetSpotId: string
|
|
1065
|
-
): ServiceDirectSpotRouteFence {
|
|
1072
|
+
entrySpotRouteFence(targetNodeRid: string, targetSpotId: string): ServiceDirectSpotRouteFence {
|
|
1066
1073
|
const generation = this.peerGeneration(targetNodeRid);
|
|
1067
1074
|
return {
|
|
1068
1075
|
spot: { spotId: targetSpotId, generation },
|
|
@@ -1089,11 +1096,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1089
1096
|
target: ServiceDirectSpotRouteFence,
|
|
1090
1097
|
durationMs: number
|
|
1091
1098
|
): Promise<boolean> {
|
|
1092
|
-
return this.requireStateful().commitSpotMessageFollowIngress(
|
|
1093
|
-
seal,
|
|
1094
|
-
target,
|
|
1095
|
-
durationMs
|
|
1096
|
-
);
|
|
1099
|
+
return this.requireStateful().commitSpotMessageFollowIngress(seal, target, durationMs);
|
|
1097
1100
|
}
|
|
1098
1101
|
|
|
1099
1102
|
forgetSpotRoute(
|
|
@@ -1224,12 +1227,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1224
1227
|
const target = String(targetNodeRid);
|
|
1225
1228
|
return this.observeStateful(
|
|
1226
1229
|
OperationKind.ActorJoin,
|
|
1227
|
-
this.requireStateful().joinActorEntrySpot(
|
|
1228
|
-
actor,
|
|
1229
|
-
target,
|
|
1230
|
-
request,
|
|
1231
|
-
timeoutMs
|
|
1232
|
-
)
|
|
1230
|
+
this.requireStateful().joinActorEntrySpot(actor, target, request, timeoutMs)
|
|
1233
1231
|
);
|
|
1234
1232
|
}
|
|
1235
1233
|
|
|
@@ -1293,13 +1291,13 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1293
1291
|
target: ZLinkBackendActorRef,
|
|
1294
1292
|
parts: MessageLike | readonly MessageLike[]
|
|
1295
1293
|
): Promise<SubmitResultValue> {
|
|
1296
|
-
return await this.requireStateful().sendToActor(
|
|
1294
|
+
return (await this.requireStateful().sendToActor(
|
|
1297
1295
|
target,
|
|
1298
1296
|
this.peerGeneration(String(target.nodeRid)),
|
|
1299
1297
|
target.generation,
|
|
1300
1298
|
encodeMultipart(parts),
|
|
1301
1299
|
source
|
|
1302
|
-
) as SubmitResultValue;
|
|
1300
|
+
)) as SubmitResultValue;
|
|
1303
1301
|
}
|
|
1304
1302
|
|
|
1305
1303
|
actorRequestToActor(
|
|
@@ -1328,12 +1326,12 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1328
1326
|
_flags?: number,
|
|
1329
1327
|
actorFence?: ZLinkBackendActorSessionSendFence
|
|
1330
1328
|
): Promise<SubmitResultValue> {
|
|
1331
|
-
return await this.requireStateful().sendBoundSession(
|
|
1329
|
+
return (await this.requireStateful().sendBoundSession(
|
|
1332
1330
|
actor,
|
|
1333
1331
|
expectedBindingGeneration,
|
|
1334
1332
|
encodeMultipart(parts),
|
|
1335
1333
|
actorFence
|
|
1336
|
-
) as SubmitResultValue;
|
|
1334
|
+
)) as SubmitResultValue;
|
|
1337
1335
|
}
|
|
1338
1336
|
|
|
1339
1337
|
closeActorBoundSession(
|
|
@@ -1380,11 +1378,11 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1380
1378
|
target: ServiceDirectSpotRouteFence,
|
|
1381
1379
|
parts: MessageLike | readonly MessageLike[]
|
|
1382
1380
|
): Promise<SubmitResultValue> {
|
|
1383
|
-
return await this.requireStateful().sendToSpot(
|
|
1381
|
+
return (await this.requireStateful().sendToSpot(
|
|
1384
1382
|
source.ref.spotId,
|
|
1385
1383
|
target,
|
|
1386
1384
|
encodeMultipart(parts)
|
|
1387
|
-
) as SubmitResultValue;
|
|
1385
|
+
)) as SubmitResultValue;
|
|
1388
1386
|
}
|
|
1389
1387
|
|
|
1390
1388
|
requestFromSpot(
|
|
@@ -1422,19 +1420,11 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1422
1420
|
);
|
|
1423
1421
|
}
|
|
1424
1422
|
|
|
1425
|
-
setSpotSubscription(
|
|
1426
|
-
state: ServiceSpotState,
|
|
1427
|
-
channelName: string,
|
|
1428
|
-
topicFilter: string
|
|
1429
|
-
): void {
|
|
1423
|
+
setSpotSubscription(state: ServiceSpotState, channelName: string, topicFilter: string): void {
|
|
1430
1424
|
this.requireStateful().setSubscription(state, channelName, topicFilter);
|
|
1431
1425
|
}
|
|
1432
1426
|
|
|
1433
|
-
unsetSpotSubscription(
|
|
1434
|
-
state: ServiceSpotState,
|
|
1435
|
-
channelName: string,
|
|
1436
|
-
topicFilter: string
|
|
1437
|
-
): void {
|
|
1427
|
+
unsetSpotSubscription(state: ServiceSpotState, channelName: string, topicFilter: string): void {
|
|
1438
1428
|
this.requireStateful().unsetSubscription(state, channelName, topicFilter);
|
|
1439
1429
|
}
|
|
1440
1430
|
|
|
@@ -1458,10 +1448,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1458
1448
|
securityIdentity: 'default',
|
|
1459
1449
|
applicationVersion: 0n,
|
|
1460
1450
|
...(this.maintenanceWave === undefined ? {} : { maintenanceWave: this.maintenanceWave }),
|
|
1461
|
-
protocolCapabilities: [
|
|
1462
|
-
SERVICE_WIRE_REQUIRED_CAPABILITY,
|
|
1463
|
-
...this.objectCapabilities
|
|
1464
|
-
].sort(),
|
|
1451
|
+
protocolCapabilities: [SERVICE_WIRE_REQUIRED_CAPABILITY, ...this.objectCapabilities].sort(),
|
|
1465
1452
|
objectRole: this.objectRole,
|
|
1466
1453
|
placementWeight: this.placementWeight,
|
|
1467
1454
|
activeCapacityLimit: this.activeCapacityLimit,
|
|
@@ -1483,10 +1470,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1483
1470
|
|
|
1484
1471
|
private scheduleMaintenance(): void {
|
|
1485
1472
|
if (this.closed || this.maintenanceTimer !== undefined) return;
|
|
1486
|
-
this.maintenanceTimer = setTimeout(
|
|
1487
|
-
this.onMaintenance,
|
|
1488
|
-
MESH_BACKEND_MAINTENANCE_INTERVAL_MS
|
|
1489
|
-
);
|
|
1473
|
+
this.maintenanceTimer = setTimeout(this.onMaintenance, MESH_BACKEND_MAINTENANCE_INTERVAL_MS);
|
|
1490
1474
|
}
|
|
1491
1475
|
|
|
1492
1476
|
private async pump(): Promise<void> {
|
|
@@ -1535,9 +1519,8 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1535
1519
|
): MeshOperationId {
|
|
1536
1520
|
const id = { high: 1n, low };
|
|
1537
1521
|
void promise.then(
|
|
1538
|
-
result => this.enqueueCompletion(id, operationKind, result),
|
|
1539
|
-
error => this.enqueueCompletion(
|
|
1540
|
-
id, operationKind, genericOperationFailure(error))
|
|
1522
|
+
(result) => this.enqueueCompletion(id, operationKind, result),
|
|
1523
|
+
(error) => this.enqueueCompletion(id, operationKind, genericOperationFailure(error))
|
|
1541
1524
|
);
|
|
1542
1525
|
return id;
|
|
1543
1526
|
}
|
|
@@ -1548,8 +1531,8 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1548
1531
|
): MeshOperationId {
|
|
1549
1532
|
const id = { high: 2n, low: pending.id };
|
|
1550
1533
|
void pending.promise.then(
|
|
1551
|
-
result => this.enqueueCompletion(id, operationKind, result),
|
|
1552
|
-
error => this.enqueueCompletion(id, operationKind, statefulOperationFailure(error))
|
|
1534
|
+
(result) => this.enqueueCompletion(id, operationKind, result),
|
|
1535
|
+
(error) => this.enqueueCompletion(id, operationKind, statefulOperationFailure(error))
|
|
1553
1536
|
);
|
|
1554
1537
|
return id;
|
|
1555
1538
|
}
|
|
@@ -1597,8 +1580,7 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1597
1580
|
this.completionCount -= 1;
|
|
1598
1581
|
if (this.completionCount === 0) {
|
|
1599
1582
|
this.clearCompletions();
|
|
1600
|
-
} else if (this.completionHead >= 1024
|
|
1601
|
-
&& this.completionHead * 2 >= this.completions.length) {
|
|
1583
|
+
} else if (this.completionHead >= 1024 && this.completionHead * 2 >= this.completions.length) {
|
|
1602
1584
|
this.completions.splice(0, this.completionHead);
|
|
1603
1585
|
this.completionHead = 0;
|
|
1604
1586
|
}
|
|
@@ -1615,17 +1597,10 @@ export class ZLinkNodeRawMeshBackend implements ZLinkBackendMeshNode {
|
|
|
1615
1597
|
const runtime = this.runtime;
|
|
1616
1598
|
if (runtime === undefined) return;
|
|
1617
1599
|
while (!batch.full) {
|
|
1618
|
-
const claim = runtime.mailbox.tryClaim(
|
|
1619
|
-
domain,
|
|
1620
|
-
MAX_DRAIN_RECORDS,
|
|
1621
|
-
Number.MAX_SAFE_INTEGER
|
|
1622
|
-
);
|
|
1600
|
+
const claim = runtime.mailbox.tryClaim(domain, MAX_DRAIN_RECORDS, Number.MAX_SAFE_INTEGER);
|
|
1623
1601
|
if (claim === undefined) break;
|
|
1624
1602
|
const owner = readyOwner(claim.owner, this.routingId, this.stateful, domain);
|
|
1625
|
-
batch.push(
|
|
1626
|
-
owner,
|
|
1627
|
-
new MailboxClaim(runtime, claim)
|
|
1628
|
-
);
|
|
1603
|
+
batch.push(owner, new MailboxClaim(runtime, claim));
|
|
1629
1604
|
}
|
|
1630
1605
|
}
|
|
1631
1606
|
|
|
@@ -1730,17 +1705,10 @@ class RawServiceSpot implements ServiceSpot {
|
|
|
1730
1705
|
String(targetSpotId),
|
|
1731
1706
|
targetSpotGeneration,
|
|
1732
1707
|
options?.entrySpot === true
|
|
1733
|
-
? this.backend.entrySpotRouteFence(
|
|
1734
|
-
String(targetNodeRid),
|
|
1735
|
-
String(targetSpotId)
|
|
1736
|
-
)
|
|
1708
|
+
? this.backend.entrySpotRouteFence(String(targetNodeRid), String(targetSpotId))
|
|
1737
1709
|
: undefined
|
|
1738
1710
|
);
|
|
1739
|
-
return this.backend.sendFromSpot(
|
|
1740
|
-
this.state,
|
|
1741
|
-
routeFence,
|
|
1742
|
-
parts
|
|
1743
|
-
);
|
|
1711
|
+
return this.backend.sendFromSpot(this.state, routeFence, parts);
|
|
1744
1712
|
}
|
|
1745
1713
|
|
|
1746
1714
|
requestToSpot(
|
|
@@ -1761,10 +1729,7 @@ class RawServiceSpot implements ServiceSpot {
|
|
|
1761
1729
|
String(targetSpotId),
|
|
1762
1730
|
targetSpotGeneration,
|
|
1763
1731
|
options?.entrySpot === true
|
|
1764
|
-
? this.backend.entrySpotRouteFence(
|
|
1765
|
-
String(targetNodeRid),
|
|
1766
|
-
String(targetSpotId)
|
|
1767
|
-
)
|
|
1732
|
+
? this.backend.entrySpotRouteFence(String(targetNodeRid), String(targetSpotId))
|
|
1768
1733
|
: undefined
|
|
1769
1734
|
);
|
|
1770
1735
|
return this.backend.requestFromSpot(
|
|
@@ -1788,14 +1753,16 @@ class RawServiceSpot implements ServiceSpot {
|
|
|
1788
1753
|
|
|
1789
1754
|
setSubscription(channelName: string, topicFilter: string, kind = 0): void {
|
|
1790
1755
|
this.requireOpen();
|
|
1791
|
-
if (kind !== 0)
|
|
1756
|
+
if (kind !== 0)
|
|
1757
|
+
throw new RangeError('Only the default logical multicast subscription kind is supported.');
|
|
1792
1758
|
this.backend.setSpotSubscription(this.state, channelName, topicFilter);
|
|
1793
1759
|
this.subscriptions.add(`${channelName}\0${topicFilter}\0${kind}`);
|
|
1794
1760
|
}
|
|
1795
1761
|
|
|
1796
1762
|
unsetSubscription(channelName: string, topicFilter: string, kind = 0): void {
|
|
1797
1763
|
this.requireOpen();
|
|
1798
|
-
if (kind !== 0)
|
|
1764
|
+
if (kind !== 0)
|
|
1765
|
+
throw new RangeError('Only the default logical multicast subscription kind is supported.');
|
|
1799
1766
|
this.backend.unsetSpotSubscription(this.state, channelName, topicFilter);
|
|
1800
1767
|
this.subscriptions.delete(`${channelName}\0${topicFilter}\0${kind}`);
|
|
1801
1768
|
}
|
|
@@ -1830,10 +1797,10 @@ function requireDirectSpotRouteFence(
|
|
|
1830
1797
|
return entryRoute;
|
|
1831
1798
|
}
|
|
1832
1799
|
if (
|
|
1833
|
-
route === undefined
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1800
|
+
route === undefined ||
|
|
1801
|
+
route.targetNodeRid !== targetNodeRid ||
|
|
1802
|
+
route.spot.spotId !== targetSpotId ||
|
|
1803
|
+
route.spot.generation !== targetSpotGeneration
|
|
1837
1804
|
) {
|
|
1838
1805
|
throw new TypeError('Direct Spot submission requires the exact resolved authority fence.');
|
|
1839
1806
|
}
|
|
@@ -1880,7 +1847,7 @@ class RawStreamSessionService implements StreamSessionService {
|
|
|
1880
1847
|
return {
|
|
1881
1848
|
state: this.state,
|
|
1882
1849
|
lifecycleGeneration: 1n,
|
|
1883
|
-
sessionCount: BigInt(new Set(bindings.map(value => value.sessionRid)).size),
|
|
1850
|
+
sessionCount: BigInt(new Set(bindings.map((value) => value.sessionRid)).size),
|
|
1884
1851
|
bindingCount: BigInt(bindings.length),
|
|
1885
1852
|
pendingMessageCount: 0n,
|
|
1886
1853
|
pendingByteCount: 0n,
|
|
@@ -1888,11 +1855,7 @@ class RawStreamSessionService implements StreamSessionService {
|
|
|
1888
1855
|
};
|
|
1889
1856
|
}
|
|
1890
1857
|
|
|
1891
|
-
lookupActor(
|
|
1892
|
-
targetNodeRid: RoutingId,
|
|
1893
|
-
actorId: string,
|
|
1894
|
-
timeoutMs = 30_000
|
|
1895
|
-
): MeshOperationId {
|
|
1858
|
+
lookupActor(targetNodeRid: RoutingId, actorId: string, timeoutMs = 30_000): MeshOperationId {
|
|
1896
1859
|
this.requireStarted();
|
|
1897
1860
|
return this.observe(
|
|
1898
1861
|
OperationKind.ActorLookup,
|
|
@@ -1920,7 +1883,8 @@ class RawStreamSessionService implements StreamSessionService {
|
|
|
1920
1883
|
sessionKey,
|
|
1921
1884
|
actor,
|
|
1922
1885
|
timeoutMs,
|
|
1923
|
-
(targetSessionRid, payloadFrame) =>
|
|
1886
|
+
(targetSessionRid, payloadFrame) =>
|
|
1887
|
+
this.deliver(targetSessionRid, actor.actorId, payloadFrame),
|
|
1924
1888
|
onBindingReplaced,
|
|
1925
1889
|
serviceSessionBindingIngressPortIfRegistered(this),
|
|
1926
1890
|
actorAuthority
|
|
@@ -1937,12 +1901,7 @@ class RawStreamSessionService implements StreamSessionService {
|
|
|
1937
1901
|
this.requireStarted();
|
|
1938
1902
|
return this.observe(
|
|
1939
1903
|
OperationKind.StreamUnbind,
|
|
1940
|
-
this.stateful.unbindSession(
|
|
1941
|
-
String(sessionRid),
|
|
1942
|
-
actor,
|
|
1943
|
-
expectedBindingGeneration,
|
|
1944
|
-
timeoutMs
|
|
1945
|
-
)
|
|
1904
|
+
this.stateful.unbindSession(String(sessionRid), actor, expectedBindingGeneration, timeoutMs)
|
|
1946
1905
|
);
|
|
1947
1906
|
}
|
|
1948
1907
|
|
|
@@ -1956,19 +1915,29 @@ class RawStreamSessionService implements StreamSessionService {
|
|
|
1956
1915
|
parts: MessageLike | readonly MessageLike[]
|
|
1957
1916
|
): Promise<SubmitResultValue> {
|
|
1958
1917
|
this.requireStarted();
|
|
1959
|
-
return await this.stateful.sendSessionToActor(
|
|
1918
|
+
return (await this.stateful.sendSessionToActor(
|
|
1960
1919
|
String(sessionRid),
|
|
1961
1920
|
actor,
|
|
1962
1921
|
encodeMultipart(parts)
|
|
1963
|
-
) as SubmitResultValue;
|
|
1922
|
+
)) as SubmitResultValue;
|
|
1964
1923
|
}
|
|
1965
1924
|
|
|
1966
|
-
private async deliver(
|
|
1925
|
+
private async deliver(
|
|
1926
|
+
sessionRid: string,
|
|
1927
|
+
actorId: string,
|
|
1928
|
+
payload: Uint8Array
|
|
1929
|
+
): Promise<boolean> {
|
|
1967
1930
|
const target = this.sessionTargets.get(sessionRid);
|
|
1968
1931
|
if (target === undefined) return false;
|
|
1969
1932
|
const operation = this.stream.send(target as unknown as BindingRoutingId);
|
|
1970
1933
|
const parts = decodeMultipartBuffers(decodeApplicationPayloadView(payload).payload);
|
|
1971
1934
|
if (parts.length === 0) return false;
|
|
1935
|
+
const actorSlot = await serviceSessionBindingIngressPortIfRegistered(this)?.actorSlot(
|
|
1936
|
+
actorId,
|
|
1937
|
+
sessionRid
|
|
1938
|
+
);
|
|
1939
|
+
if (actorSlot === undefined) return false;
|
|
1940
|
+
parts[0] = Buffer.from(streamFrameWithActorSlot(parts[0]!, actorSlot));
|
|
1972
1941
|
let submit = operation.message(parts[0]!);
|
|
1973
1942
|
for (let index = 1; index < parts.length; index++) {
|
|
1974
1943
|
submit = submit.message(parts[index]!);
|
|
@@ -1985,20 +1954,14 @@ class RawStreamSessionService implements StreamSessionService {
|
|
|
1985
1954
|
// Let the socket monitor drive the existing STREAM close/unbind
|
|
1986
1955
|
// lifecycle instead of maintaining a second session-close state.
|
|
1987
1956
|
disconnectStreamPeer(this.stream, target);
|
|
1988
|
-
throw new ZLinkBackendResultError(
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
error.nativeErrno,
|
|
1992
|
-
{ cause: error }
|
|
1993
|
-
);
|
|
1957
|
+
throw new ZLinkBackendResultError('submit', error.result, error.nativeErrno, {
|
|
1958
|
+
cause: error
|
|
1959
|
+
});
|
|
1994
1960
|
case SubmitResult.Backpressured:
|
|
1995
1961
|
case SubmitResult.NotAdmitted:
|
|
1996
|
-
throw new ZLinkBackendResultError(
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
error.nativeErrno,
|
|
2000
|
-
{ cause: error }
|
|
2001
|
-
);
|
|
1962
|
+
throw new ZLinkBackendResultError('submit', error.result, error.nativeErrno, {
|
|
1963
|
+
cause: error
|
|
1964
|
+
});
|
|
2002
1965
|
default:
|
|
2003
1966
|
throw error;
|
|
2004
1967
|
}
|
|
@@ -2012,12 +1975,22 @@ class RawStreamSessionService implements StreamSessionService {
|
|
|
2012
1975
|
}
|
|
2013
1976
|
}
|
|
2014
1977
|
|
|
1978
|
+
function streamFrameWithActorSlot(frame: Uint8Array, actorSlot: number): Uint8Array {
|
|
1979
|
+
const decodedFrame = decodeStreamWireFrame(frame);
|
|
1980
|
+
const decodedHeader = decodeStreamWireHeader(decodedFrame.header);
|
|
1981
|
+
return encodeStreamWireFrame(
|
|
1982
|
+
encodeStreamWireHeader({ ...decodedHeader, actorSlot }),
|
|
1983
|
+
decodedFrame.payload
|
|
1984
|
+
);
|
|
1985
|
+
}
|
|
1986
|
+
|
|
2015
1987
|
class RawReadyBatch implements ReadyBatch {
|
|
2016
1988
|
readonly records: ReadyRecord[] = [];
|
|
2017
1989
|
private readonly claims: RawClaim[] = [];
|
|
2018
1990
|
|
|
2019
1991
|
constructor(private readonly capacity: number) {
|
|
2020
|
-
if (!Number.isInteger(capacity) || capacity < 1)
|
|
1992
|
+
if (!Number.isInteger(capacity) || capacity < 1)
|
|
1993
|
+
throw new RangeError('Ready capacity must be positive.');
|
|
2021
1994
|
}
|
|
2022
1995
|
|
|
2023
1996
|
get full(): boolean {
|
|
@@ -2054,7 +2027,7 @@ class RawReceiveBatch implements ReceiveBatch {
|
|
|
2054
2027
|
private readonly capacity: number,
|
|
2055
2028
|
readonly partCapacity: number
|
|
2056
2029
|
) {
|
|
2057
|
-
if ([capacity, partCapacity].some(value => !Number.isInteger(value) || value < 1)) {
|
|
2030
|
+
if ([capacity, partCapacity].some((value) => !Number.isInteger(value) || value < 1)) {
|
|
2058
2031
|
throw new RangeError('Receive batch capacities must be positive.');
|
|
2059
2032
|
}
|
|
2060
2033
|
this.receiveCapacity = capacity;
|
|
@@ -2065,7 +2038,11 @@ class RawReceiveBatch implements ReceiveBatch {
|
|
|
2065
2038
|
}
|
|
2066
2039
|
|
|
2067
2040
|
reset(messageCapacity = this.capacity): void {
|
|
2068
|
-
if (
|
|
2041
|
+
if (
|
|
2042
|
+
!Number.isInteger(messageCapacity) ||
|
|
2043
|
+
messageCapacity < 1 ||
|
|
2044
|
+
messageCapacity > this.capacity
|
|
2045
|
+
) {
|
|
2069
2046
|
throw new RangeError('Receive limit must be within the batch capacity.');
|
|
2070
2047
|
}
|
|
2071
2048
|
this.receiveCapacity = messageCapacity;
|
|
@@ -2111,10 +2088,7 @@ class MailboxClaim implements RawClaim {
|
|
|
2111
2088
|
throw error;
|
|
2112
2089
|
}
|
|
2113
2090
|
const nextParts = decoded.parts.length;
|
|
2114
|
-
if (
|
|
2115
|
-
records.length >= capacity.messageCapacity
|
|
2116
|
-
|| parts + nextParts > capacity.partCapacity
|
|
2117
|
-
) {
|
|
2091
|
+
if (records.length >= capacity.messageCapacity || parts + nextParts > capacity.partCapacity) {
|
|
2118
2092
|
for (const part of decoded.parts) part.close();
|
|
2119
2093
|
this.remaining = this.claim.records.slice(index);
|
|
2120
2094
|
break;
|
|
@@ -2144,31 +2118,33 @@ class CompletionClaim implements RawClaim {
|
|
|
2144
2118
|
const payload = this.completion.result.payload;
|
|
2145
2119
|
return {
|
|
2146
2120
|
ok: true,
|
|
2147
|
-
records: [
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2121
|
+
records: [
|
|
2122
|
+
{
|
|
2123
|
+
kind: ReceiveKind.Completion,
|
|
2124
|
+
domain: ReadyDomain.Infrastructure,
|
|
2125
|
+
sourceNodeRid: null,
|
|
2126
|
+
sourceSpotId: null,
|
|
2127
|
+
sourceBindingGeneration: 0n,
|
|
2128
|
+
sourceActor: null,
|
|
2129
|
+
operationId: this.completion.operationId,
|
|
2130
|
+
operationKind: this.completion.operationKind,
|
|
2131
|
+
channelName: null,
|
|
2132
|
+
topic: null,
|
|
2133
|
+
applicationMetadata: null,
|
|
2134
|
+
kindData:
|
|
2135
|
+
'kindData' in this.completion.result ? (this.completion.result.kindData ?? null) : null,
|
|
2136
|
+
terminalResult: this.completion.result.terminalResult,
|
|
2137
|
+
failureErrno: this.completion.result.failureCode,
|
|
2138
|
+
parts:
|
|
2139
|
+
payload === undefined
|
|
2140
|
+
? []
|
|
2141
|
+
: payload.contentType === MULTIPART_CONTENT_TYPE
|
|
2142
|
+
? decodeMultipart(payload.payload)
|
|
2143
|
+
: [Message.from(payload.payload)],
|
|
2144
|
+
reply: () => SubmitResult.InvalidState,
|
|
2145
|
+
replyActorJoin: () => SubmitResult.NotSupported
|
|
2146
|
+
}
|
|
2147
|
+
]
|
|
2172
2148
|
};
|
|
2173
2149
|
}
|
|
2174
2150
|
|
|
@@ -2196,12 +2172,11 @@ function decodeMultipartRecord(
|
|
|
2196
2172
|
// multi-frame infrastructure control (Prepare + sideband) from being
|
|
2197
2173
|
// misread as a 2-frame application envelope and dropped as invalid_frame.
|
|
2198
2174
|
if (record.parts.length === 1 || record.domain === 'infrastructure') {
|
|
2199
|
-
const request = record.requestSequence !== undefined
|
|
2200
|
-
&& record.sourceRoutingId !== undefined;
|
|
2175
|
+
const request = record.requestSequence !== undefined && record.sourceRoutingId !== undefined;
|
|
2201
2176
|
return {
|
|
2202
2177
|
kind: request ? ReceiveKind.NodeRequest : ReceiveKind.NodeSend,
|
|
2203
2178
|
domain: readyDomain(record.domain),
|
|
2204
|
-
sourceNodeRid: record.sourceRoutingId as RoutingId | undefined ?? null,
|
|
2179
|
+
sourceNodeRid: (record.sourceRoutingId as RoutingId | undefined) ?? null,
|
|
2205
2180
|
sourceSpotId: null,
|
|
2206
2181
|
sourceBindingGeneration: 0n,
|
|
2207
2182
|
sourceActor: null,
|
|
@@ -2216,17 +2191,20 @@ function decodeMultipartRecord(
|
|
|
2216
2191
|
terminalResult: 0,
|
|
2217
2192
|
failureErrno: 0,
|
|
2218
2193
|
...receiveIngressLifecycle(record),
|
|
2219
|
-
parts: record.parts.map(part => Message.from(part)),
|
|
2194
|
+
parts: record.parts.map((part) => Message.from(part)),
|
|
2220
2195
|
reply(parts) {
|
|
2221
2196
|
if (!request) return SubmitResult.InvalidState;
|
|
2222
2197
|
const values = Array.isArray(parts) ? parts : [parts];
|
|
2223
2198
|
if (values.length === 0) return SubmitResult.InvalidState;
|
|
2224
|
-
runtime.replyService(
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2199
|
+
runtime.replyService(
|
|
2200
|
+
{
|
|
2201
|
+
sourceRoutingId: record.sourceRoutingId!,
|
|
2202
|
+
...(record.sourceRoute === undefined ? {} : { sourceRoute: record.sourceRoute }),
|
|
2203
|
+
requestSequence: record.requestSequence!,
|
|
2204
|
+
...(record.reply === undefined ? {} : { reply: record.reply })
|
|
2205
|
+
},
|
|
2206
|
+
values.map((value) => Buffer.from(messageBytesView(value)))
|
|
2207
|
+
);
|
|
2230
2208
|
return SubmitResult.Ok;
|
|
2231
2209
|
},
|
|
2232
2210
|
replyActorJoin: () => SubmitResult.NotSupported
|
|
@@ -2236,27 +2214,32 @@ function decodeMultipartRecord(
|
|
|
2236
2214
|
const command = header[3]!;
|
|
2237
2215
|
const payloadFrame = record.parts[1]!;
|
|
2238
2216
|
const application = decodeApplicationEnvelope(payloadFrame);
|
|
2239
|
-
const channelName = record.owner.startsWith('channel:')
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2217
|
+
const channelName = record.owner.startsWith('channel:')
|
|
2218
|
+
? record.owner.slice('channel:'.length)
|
|
2219
|
+
: null;
|
|
2220
|
+
const operationId =
|
|
2221
|
+
record.correlation === undefined
|
|
2222
|
+
? { high: 0n, low: 0n }
|
|
2223
|
+
: { high: 1n, low: record.correlation };
|
|
2224
|
+
const kind =
|
|
2225
|
+
command === 16
|
|
2226
|
+
? ReceiveKind.NodeSend
|
|
2227
|
+
: command === 17
|
|
2228
|
+
? ReceiveKind.NodeRequest
|
|
2229
|
+
: command === 18
|
|
2230
|
+
? ReceiveKind.ChannelSend
|
|
2231
|
+
: ReceiveKind.ChannelRequest;
|
|
2232
|
+
const operationKind =
|
|
2233
|
+
kind === ReceiveKind.NodeRequest
|
|
2234
|
+
? OperationKind.NodeRequest
|
|
2235
|
+
: kind === ReceiveKind.ChannelRequest
|
|
2236
|
+
? OperationKind.ChannelRequest
|
|
2237
|
+
: 0;
|
|
2255
2238
|
const ingressLifecycle = receiveIngressLifecycle(record);
|
|
2256
2239
|
return {
|
|
2257
2240
|
kind,
|
|
2258
2241
|
domain: readyDomain(record.domain),
|
|
2259
|
-
sourceNodeRid: record.sourceRoutingId as RoutingId | undefined ?? null,
|
|
2242
|
+
sourceNodeRid: (record.sourceRoutingId as RoutingId | undefined) ?? null,
|
|
2260
2243
|
sourceSpotId: null,
|
|
2261
2244
|
sourceBindingGeneration: 0n,
|
|
2262
2245
|
sourceActor: null,
|
|
@@ -2286,22 +2269,27 @@ function decodeStatefulRecord(
|
|
|
2286
2269
|
stateful: ServiceStatefulMailboxData
|
|
2287
2270
|
): ReceiveRecord {
|
|
2288
2271
|
const payloadFrame = record.parts.length < 2 ? undefined : record.parts[1];
|
|
2289
|
-
const canonicalActorJoin =
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2272
|
+
const canonicalActorJoin =
|
|
2273
|
+
stateful.kindData?.kind === 'actorControl' &&
|
|
2274
|
+
stateful.kindData.canonicalActorJoin !== undefined;
|
|
2275
|
+
const canonicalActorJoinPayload =
|
|
2276
|
+
stateful.operationKind === OperationKind.ActorJoin &&
|
|
2277
|
+
stateful.canonicalApplicationPayload !== undefined;
|
|
2293
2278
|
const application = canonicalActorJoinPayload
|
|
2294
2279
|
? stateful.canonicalApplicationPayload
|
|
2295
|
-
:
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2280
|
+
: payloadFrame === undefined
|
|
2281
|
+
? undefined
|
|
2282
|
+
: decodeApplicationEnvelope(payloadFrame);
|
|
2283
|
+
const operationId =
|
|
2284
|
+
record.correlation === undefined
|
|
2285
|
+
? { high: 0n, low: 0n }
|
|
2286
|
+
: { high: 2n, low: record.correlation };
|
|
2299
2287
|
const ingressLifecycle = receiveIngressLifecycle(record);
|
|
2300
2288
|
return {
|
|
2301
2289
|
kind: stateful.receiveKind,
|
|
2302
2290
|
domain: readyDomain(record.domain),
|
|
2303
|
-
sourceNodeRid: record.sourceRoutingId as RoutingId | undefined ?? null,
|
|
2304
|
-
sourceSpotId: stateful.sourceSpotId as RoutingId | undefined ?? null,
|
|
2291
|
+
sourceNodeRid: (record.sourceRoutingId as RoutingId | undefined) ?? null,
|
|
2292
|
+
sourceSpotId: (stateful.sourceSpotId as RoutingId | undefined) ?? null,
|
|
2305
2293
|
sourceBindingGeneration: stateful.sourceBindingGeneration ?? 0n,
|
|
2306
2294
|
sourceActor: stateful.sourceActor ?? null,
|
|
2307
2295
|
operationId,
|
|
@@ -2319,11 +2307,12 @@ function decodeStatefulRecord(
|
|
|
2319
2307
|
terminalResult: 0,
|
|
2320
2308
|
failureErrno: 0,
|
|
2321
2309
|
...ingressLifecycle,
|
|
2322
|
-
parts:
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2310
|
+
parts:
|
|
2311
|
+
application === undefined
|
|
2312
|
+
? []
|
|
2313
|
+
: canonicalActorJoinPayload
|
|
2314
|
+
? [Message.from(application.payload)]
|
|
2315
|
+
: decodeMultipart(application.payload),
|
|
2327
2316
|
...(stateful.isPending === undefined ? {} : { isPending: stateful.isPending }),
|
|
2328
2317
|
...(stateful.deadlineUnixMs === undefined ? {} : { deadlineUnixMs: stateful.deadlineUnixMs }),
|
|
2329
2318
|
...(stateful.messageFollowOrigin === undefined
|
|
@@ -2334,19 +2323,18 @@ function decodeStatefulRecord(
|
|
|
2334
2323
|
: { onTerminalCompletion: stateful.onTerminalCompletion }),
|
|
2335
2324
|
reply(parts) {
|
|
2336
2325
|
if (stateful.reply === undefined) return SubmitResult.InvalidState;
|
|
2337
|
-
return stateful.reply(
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
encodeMultipart(parts)
|
|
2341
|
-
) ? SubmitResult.Ok : SubmitResult.InvalidState;
|
|
2326
|
+
return stateful.reply(RequestResult.Ok, 0, encodeMultipart(parts))
|
|
2327
|
+
? SubmitResult.Ok
|
|
2328
|
+
: SubmitResult.InvalidState;
|
|
2342
2329
|
},
|
|
2343
2330
|
replyActorJoin(joinResult, parts, _flags, _replyContentType) {
|
|
2344
2331
|
if (stateful.reply === undefined || stateful.targetSpot === undefined) {
|
|
2345
2332
|
return SubmitResult.InvalidState;
|
|
2346
2333
|
}
|
|
2347
|
-
const membershipEpoch =
|
|
2348
|
-
|
|
2349
|
-
|
|
2334
|
+
const membershipEpoch =
|
|
2335
|
+
stateful.kindData?.kind === 'actorControl'
|
|
2336
|
+
? stateful.kindData.currentMembershipEpoch
|
|
2337
|
+
: undefined;
|
|
2350
2338
|
if (joinResult === 0 && membershipEpoch === undefined) {
|
|
2351
2339
|
return SubmitResult.InvalidState;
|
|
2352
2340
|
}
|
|
@@ -2354,26 +2342,19 @@ function decodeStatefulRecord(
|
|
|
2354
2342
|
if (canonicalActorJoin && replyParts.length > 1) {
|
|
2355
2343
|
return SubmitResult.InvalidState;
|
|
2356
2344
|
}
|
|
2357
|
-
const replyPayload = replyParts.length === 0
|
|
2358
|
-
|
|
2359
|
-
:
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
// valid receive chunk cap for this join's relocation state chunks —
|
|
2371
|
-
// a conservative, recompute-stable bound (never lowered).
|
|
2372
|
-
...(joinResult === 0
|
|
2373
|
-
? { receiveChunkLimitBytes: ACTOR_JOIN_ADVERTISED_RECEIVE_CHUNK_LIMIT_BYTES }
|
|
2374
|
-
: {})
|
|
2375
|
-
}
|
|
2376
|
-
);
|
|
2345
|
+
const replyPayload = replyParts.length === 0 ? undefined : encodeMultipart(replyParts);
|
|
2346
|
+
const accepted = stateful.reply(RequestResult.Ok, 0, replyPayload, {
|
|
2347
|
+
kind: 'actorJoin',
|
|
2348
|
+
joinResult: joinResult === 0 ? 0 : 1,
|
|
2349
|
+
spot: stateful.targetSpot,
|
|
2350
|
+
...(membershipEpoch === undefined ? {} : { membershipEpoch }),
|
|
2351
|
+
// Spec 15 §4.2: the accepted admission reply carries the target's
|
|
2352
|
+
// valid receive chunk cap for this join's relocation state chunks —
|
|
2353
|
+
// a conservative, recompute-stable bound (never lowered).
|
|
2354
|
+
...(joinResult === 0
|
|
2355
|
+
? { receiveChunkLimitBytes: ACTOR_JOIN_ADVERTISED_RECEIVE_CHUNK_LIMIT_BYTES }
|
|
2356
|
+
: {})
|
|
2357
|
+
});
|
|
2377
2358
|
return accepted ? SubmitResult.Ok : SubmitResult.InvalidState;
|
|
2378
2359
|
},
|
|
2379
2360
|
replyFailure(terminalResult, failureCode) {
|
|
@@ -2415,9 +2396,8 @@ function readyOwner(
|
|
|
2415
2396
|
}
|
|
2416
2397
|
if (owner.startsWith('actor:')) {
|
|
2417
2398
|
const separator = owner.indexOf('\0', 'actor:'.length);
|
|
2418
|
-
const actorId =
|
|
2419
|
-
? owner.slice('actor:'.length)
|
|
2420
|
-
: owner.slice('actor:'.length, separator);
|
|
2399
|
+
const actorId =
|
|
2400
|
+
separator < 0 ? owner.slice('actor:'.length) : owner.slice('actor:'.length, separator);
|
|
2421
2401
|
const generation = separator < 0 ? 0n : BigInt(owner.slice(separator + 1));
|
|
2422
2402
|
const current = stateful?.actor(actorId);
|
|
2423
2403
|
return {
|
|
@@ -2442,9 +2422,7 @@ function readyOwner(
|
|
|
2442
2422
|
}
|
|
2443
2423
|
|
|
2444
2424
|
function readyDomain(domain: ServiceMailboxDomain): number {
|
|
2445
|
-
return domain === 'infrastructure'
|
|
2446
|
-
? ReadyDomain.Infrastructure
|
|
2447
|
-
: ReadyDomain.Application;
|
|
2425
|
+
return domain === 'infrastructure' ? ReadyDomain.Infrastructure : ReadyDomain.Application;
|
|
2448
2426
|
}
|
|
2449
2427
|
|
|
2450
2428
|
/**
|
|
@@ -2506,9 +2484,7 @@ function encodeMultipart(parts: MessageLike | readonly MessageLike[]) {
|
|
|
2506
2484
|
};
|
|
2507
2485
|
}
|
|
2508
2486
|
|
|
2509
|
-
function encodeMultipartApplicationFrame(
|
|
2510
|
-
parts: MessageLike | readonly MessageLike[]
|
|
2511
|
-
): Buffer {
|
|
2487
|
+
function encodeMultipartApplicationFrame(parts: MessageLike | readonly MessageLike[]): Buffer {
|
|
2512
2488
|
const values = Array.isArray(parts) ? parts : [parts];
|
|
2513
2489
|
if (values.length === 0) throw new TypeError('Multipart payload must contain at least one part.');
|
|
2514
2490
|
return encodeMultipartApplicationPayload(
|
|
@@ -2553,9 +2529,9 @@ function decodeApplicationEnvelope(frame: Uint8Array) {
|
|
|
2553
2529
|
const payloadLength = bytes.readUInt32BE(offset);
|
|
2554
2530
|
offset += 4;
|
|
2555
2531
|
if (
|
|
2556
|
-
packetName !== MULTIPART_PACKET_NAME
|
|
2557
|
-
|
|
2558
|
-
|
|
2532
|
+
packetName !== MULTIPART_PACKET_NAME ||
|
|
2533
|
+
contentType !== MULTIPART_CONTENT_TYPE ||
|
|
2534
|
+
payloadLength !== bytes.length - offset
|
|
2559
2535
|
) {
|
|
2560
2536
|
throw new ServiceWireProtocolError('Unexpected M6A application payload.');
|
|
2561
2537
|
}
|
|
@@ -2613,7 +2589,8 @@ function messageBytesView(value: MessageLike): Uint8Array {
|
|
|
2613
2589
|
}
|
|
2614
2590
|
|
|
2615
2591
|
function requireRawReadyBatch(batch: ReadyBatch): RawReadyBatch {
|
|
2616
|
-
if (!(batch instanceof RawReadyBatch))
|
|
2592
|
+
if (!(batch instanceof RawReadyBatch))
|
|
2593
|
+
throw new TypeError('Ready batch belongs to another backend.');
|
|
2617
2594
|
return batch;
|
|
2618
2595
|
}
|
|
2619
2596
|
|
|
@@ -2623,12 +2600,16 @@ function stateCode(state: ServiceNodeDescriptor['state']): number {
|
|
|
2623
2600
|
|
|
2624
2601
|
function peerStateCode(state: ServiceNodeDescriptor['state']): number {
|
|
2625
2602
|
switch (state) {
|
|
2626
|
-
case 'preparing':
|
|
2603
|
+
case 'preparing':
|
|
2604
|
+
return 2;
|
|
2627
2605
|
case 'serving':
|
|
2628
|
-
case 'retiring':
|
|
2629
|
-
|
|
2606
|
+
case 'retiring':
|
|
2607
|
+
return 3;
|
|
2608
|
+
case 'draining':
|
|
2609
|
+
return 4;
|
|
2630
2610
|
case 'stopped':
|
|
2631
|
-
case 'error':
|
|
2611
|
+
case 'error':
|
|
2612
|
+
return 5;
|
|
2632
2613
|
}
|
|
2633
2614
|
}
|
|
2634
2615
|
|
|
@@ -2636,8 +2617,7 @@ function createLifecycleGeneration(): bigint {
|
|
|
2636
2617
|
// Node's public Spot context exposes this lifecycle token as a number. Keep
|
|
2637
2618
|
// the opaque equality token within the exact range that surface can carry;
|
|
2638
2619
|
// lifecycle ordering is never inferred from its numeric value.
|
|
2639
|
-
const generation = randomBytes(8).readBigUInt64BE()
|
|
2640
|
-
& BigInt(Number.MAX_SAFE_INTEGER);
|
|
2620
|
+
const generation = randomBytes(8).readBigUInt64BE() & BigInt(Number.MAX_SAFE_INTEGER);
|
|
2641
2621
|
return generation === 0n ? 1n : generation;
|
|
2642
2622
|
}
|
|
2643
2623
|
|