@zlink-systems/framework 0.30.3 → 0.32.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/Actors/ZLinkActor.d.ts +2 -0
- package/dist/contracts/Actors/ZLinkSessionBindingIdentity.d.ts +6 -0
- package/dist/contracts/Actors/ZLinkSessionBindingIdentity.js +2 -0
- package/dist/contracts/Actors/index.d.ts +1 -0
- package/dist/contracts/Actors/index.js +1 -0
- package/dist/contracts/Common/CoreTypes.d.ts +1 -0
- package/dist/contracts/Common/HandlerMessageType.d.ts +8 -0
- package/dist/contracts/Common/HandlerMessageType.js +41 -0
- package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +1 -1
- package/dist/contracts/Common/ZLinkEncodedPayload.js +12 -20
- package/dist/contracts/Common/ZLinkMessage.js +11 -7
- package/dist/contracts/Common/encoded-payload-storage.d.ts +0 -2
- package/dist/contracts/Common/encoded-payload-storage.js +4 -16
- package/dist/contracts/Common/index.d.ts +1 -1
- package/dist/contracts/Common/payload-slab.d.ts +4 -0
- package/dist/contracts/Common/payload-slab.js +30 -0
- package/dist/contracts/Configuration/RegistrationBuilders.js +15 -9
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +19 -0
- package/dist/contracts/Handlers/Contexts.d.ts +1 -0
- package/dist/contracts/Locations/Authority.d.ts +2 -0
- package/dist/internal.d.ts +9 -0
- package/dist/internal.js +23 -1
- package/dist/nest-integration.d.ts +1 -0
- package/dist/nest-integration.js +3 -1
- package/dist/runtime/actors/actor-client.d.ts +6 -2
- package/dist/runtime/actors/actor-client.js +120 -82
- package/dist/runtime/actors/actor-context.js +16 -5
- package/dist/runtime/actors/actor-execution-context.js +2 -2
- package/dist/runtime/actors/actor-handoff.d.ts +12 -1
- package/dist/runtime/actors/actor-handoff.js +79 -34
- package/dist/runtime/actors/actor-join-deferred-scope.js +6 -6
- package/dist/runtime/actors/actor-local-native-join.d.ts +2 -2
- package/dist/runtime/actors/actor-local-native-join.js +19 -17
- package/dist/runtime/actors/actor-mailbox.d.ts +1 -1
- package/dist/runtime/actors/actor-remote-joiner.d.ts +2 -2
- package/dist/runtime/actors/actor-remote-joiner.js +4 -4
- package/dist/runtime/actors/actor-routed-join-transport.d.ts +9 -3
- package/dist/runtime/actors/actor-routed-json-request.d.ts +3 -0
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -2
- package/dist/runtime/actors/actor-runtime-state.d.ts +1 -1
- package/dist/runtime/actors/spot-actor-dispatch.d.ts +9 -5
- package/dist/runtime/actors/spot-actor-dispatch.js +60 -38
- package/dist/runtime/admission.d.ts +6 -4
- package/dist/runtime/admission.js +21 -10
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +1 -0
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +3 -0
- package/dist/runtime/backend/contracts/index.d.ts +26 -10
- package/dist/runtime/backend/mesh-completion-table.d.ts +7 -1
- package/dist/runtime/backend/mesh-completion-table.js +84 -20
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +19 -6
- package/dist/runtime/backend/mesh-dispatch-pump.js +246 -147
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -2
- package/dist/runtime/backend/node/node-backend-adapter-support.js +27 -19
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +5 -2
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +70 -13
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
- package/dist/runtime/backend/node/node-event-loop-poller.js +4 -3
- package/dist/runtime/backend/node/node-mesh-backend-adapter.js +5 -1
- package/dist/runtime/backend/node/node-raw-binding-port.d.ts +7 -2
- package/dist/runtime/backend/node/node-raw-binding-port.js +99 -63
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +34 -16
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +210 -106
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +20 -6
- package/dist/runtime/backend/raw-binding-port.d.ts +6 -3
- package/dist/runtime/channels/channel-clients.js +3 -3
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +11 -7
- package/dist/runtime/channels/channel-dispatch-pipeline.js +40 -22
- package/dist/runtime/channels/channel-dispatch-services.d.ts +3 -1
- package/dist/runtime/channels/channel-dispatch-services.js +7 -6
- package/dist/runtime/channels/channel-dispatchers.d.ts +13 -6
- package/dist/runtime/channels/channel-dispatchers.js +57 -36
- package/dist/runtime/channels/channel-envelope.d.ts +2 -2
- package/dist/runtime/channels/channel-envelope.js +609 -83
- package/dist/runtime/channels/channel-multipart.d.ts +1 -0
- package/dist/runtime/channels/channel-multipart.js +10 -6
- package/dist/runtime/channels/channel-outbound-operations.d.ts +6 -9
- package/dist/runtime/channels/channel-outbound-operations.js +107 -105
- package/dist/runtime/channels/channel-receive-loops.d.ts +9 -7
- package/dist/runtime/channels/channel-receive-loops.js +126 -90
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +23 -6
- package/dist/runtime/channels/channel-runtime-lifecycle.js +47 -38
- package/dist/runtime/channels/channel-runtime-manager.d.ts +13 -6
- package/dist/runtime/channels/channel-runtime-manager.js +32 -14
- package/dist/runtime/channels/channel-socket-registry.d.ts +28 -4
- package/dist/runtime/channels/channel-socket-registry.js +9 -1
- package/dist/runtime/channels/channel-transports.d.ts +23 -16
- package/dist/runtime/channels/channel-transports.js +139 -119
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +4 -4
- package/dist/runtime/channels/dispatch-error-reporter.js +5 -5
- package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/local-spot-route-transport.d.ts +5 -2
- package/dist/runtime/channels/local-spot-route-transport.js +15 -18
- package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +6 -3
- package/dist/runtime/channels/router-socket-spot-route-transport.js +33 -19
- package/dist/runtime/channels/source-spot-router.d.ts +6 -3
- package/dist/runtime/channels/source-spot-router.js +34 -23
- package/dist/runtime/channels/spot-node-route-transport.d.ts +6 -3
- package/dist/runtime/channels/spot-node-route-transport.js +23 -17
- package/dist/runtime/channels/spot-route-bridge-transport.d.ts +6 -3
- package/dist/runtime/channels/spot-route-bridge-transport.js +38 -24
- package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +8 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +36 -23
- package/dist/runtime/diagnostics/dispatch-error-details.js +9 -3
- package/dist/runtime/diagnostics/message-flow-bootstrap.d.ts +1 -0
- package/dist/runtime/diagnostics/message-flow-bootstrap.js +8 -0
- package/dist/runtime/diagnostics/message-flow-delivery.d.ts +47 -0
- package/dist/runtime/diagnostics/message-flow-delivery.js +149 -0
- package/dist/runtime/diagnostics/message-flow-record.d.ts +50 -0
- package/dist/runtime/diagnostics/message-flow-record.js +228 -0
- package/dist/runtime/diagnostics/message-flow-worker.d.ts +1 -0
- package/dist/runtime/diagnostics/message-flow-worker.js +118 -0
- package/dist/runtime/diagnostics/message-flow.d.ts +7 -19
- package/dist/runtime/diagnostics/message-flow.js +42 -290
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +4 -3
- package/dist/runtime/diagnostics/runtime-metrics.js +8 -4
- package/dist/runtime/execution/index.d.ts +1 -0
- package/dist/runtime/execution/index.js +6 -3
- package/dist/runtime/execution/serial-execution-queue.d.ts +26 -13
- package/dist/runtime/execution/serial-execution-queue.js +75 -71
- package/dist/runtime/foundation/durable-service-request.d.ts +12 -3
- package/dist/runtime/foundation/durable-service-request.js +158 -73
- package/dist/runtime/foundation/operation-registry.d.ts +33 -3
- package/dist/runtime/foundation/operation-registry.js +272 -33
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +62 -23
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +373 -194
- package/dist/runtime/foundation/request-runtime.d.ts +17 -0
- package/dist/runtime/foundation/request-runtime.js +163 -0
- package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
- package/dist/runtime/foundation/service-discovery-registry.js +6 -0
- package/dist/runtime/foundation/service-liveness-registry.d.ts +1 -1
- package/dist/runtime/foundation/service-mailbox.d.ts +4 -2
- package/dist/runtime/foundation/service-mailbox.js +4 -1
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -2
- package/dist/runtime/foundation/service-relocation-object-owner.js +12 -5
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +7 -2
- package/dist/runtime/foundation/service-stateful-registry.d.ts +6 -2
- package/dist/runtime/foundation/service-stateful-registry.js +38 -17
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +91 -26
- package/dist/runtime/foundation/service-stateful-runtime.js +245 -120
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -0
- package/dist/runtime/foundation/service-stateful-wire-codec.js +15 -0
- package/dist/runtime/foundation/service-topology-registry.d.ts +2 -0
- package/dist/runtime/foundation/service-topology-registry.js +13 -3
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +12 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +5 -1
- package/dist/runtime/foundation/service-wire-m6a-codec.js +50 -15
- package/dist/runtime/host/actor-packet-relay.d.ts +5 -6
- package/dist/runtime/host/actor-packet-relay.js +58 -57
- package/dist/runtime/host/actor-placement-coordinator.d.ts +1 -1
- package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
- package/dist/runtime/host/actor-runtime-options-factory.js +3 -2
- package/dist/runtime/host/actor-transfer-runtime.d.ts +3 -3
- package/dist/runtime/host/application-job-queue.d.ts +7 -5
- package/dist/runtime/host/application-job-queue.js +33 -21
- package/dist/runtime/host/bound-session-relay.js +0 -1
- package/dist/runtime/host/channel-runtime-options-factory.d.ts +2 -0
- package/dist/runtime/host/channel-runtime-options-factory.js +1 -0
- package/dist/runtime/host/entry-actor-runtime.d.ts +5 -2
- package/dist/runtime/host/entry-actor-runtime.js +2 -2
- package/dist/runtime/host/index.d.ts +106 -37
- package/dist/runtime/host/index.js +303 -151
- package/dist/runtime/host/location-runtime-owner.d.ts +2 -2
- package/dist/runtime/host/location-runtime-owner.js +1 -1
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +195 -45
- package/dist/runtime/host/service-relocation-host-runtime.js +257 -144
- package/dist/runtime/host/spot-address-transport.d.ts +3 -0
- package/dist/runtime/host/spot-address-transport.js +73 -76
- package/dist/runtime/host/spot-runtime-options-factory.js +2 -0
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -1
- package/dist/runtime/host/user-spot-creation-coordinator.js +49 -21
- package/dist/runtime/internal-observation.d.ts +1 -0
- package/dist/runtime/internal-observation.js +5 -0
- package/dist/runtime/locations/actor-location-claims.d.ts +1 -1
- package/dist/runtime/locations/actor-location-claims.js +15 -6
- package/dist/runtime/locations/auto-connect-loop.d.ts +0 -1
- package/dist/runtime/locations/auto-connect-loop.js +25 -19
- package/dist/runtime/locations/auto-connect-planner.js +2 -5
- package/dist/runtime/locations/auto-connect-reconciler.d.ts +1 -0
- package/dist/runtime/locations/auto-connect-reconciler.js +35 -23
- package/dist/runtime/locations/in-memory-authority-store.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.js +15 -5
- package/dist/runtime/locations/in-memory-location-store.d.ts +0 -2
- package/dist/runtime/locations/in-memory-location-store.js +1 -38
- package/dist/runtime/locations/lifecycle.d.ts +1 -1
- package/dist/runtime/locations/lifecycle.js +2 -2
- package/dist/runtime/locations/location-store-repository.d.ts +0 -1
- package/dist/runtime/locations/location-store-repository.js +163 -246
- package/dist/runtime/locations/resolvers.d.ts +8 -1
- package/dist/runtime/locations/resolvers.js +16 -2
- package/dist/runtime/locations/runtime.d.ts +3 -3
- package/dist/runtime/locations/runtime.js +12 -16
- package/dist/runtime/messaging/creation-payload-codec.js +8 -7
- package/dist/runtime/messaging/framework-json-v1.d.ts +1 -1
- package/dist/runtime/messaging/framework-json-v1.js +6 -2
- package/dist/runtime/messaging/payload-codec.js +21 -35
- package/dist/runtime/messaging/request-deadline.d.ts +4 -2
- package/dist/runtime/messaging/request-deadline.js +40 -25
- package/dist/runtime/messaging/request-result.d.ts +14 -1
- package/dist/runtime/messaging/request-result.js +74 -13
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +4 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +17 -7
- package/dist/runtime/spots/index.d.ts +28 -7
- package/dist/runtime/spots/index.js +31 -6
- package/dist/runtime/spots/spot-activation-registry.d.ts +3 -2
- package/dist/runtime/spots/spot-activation-registry.js +13 -8
- package/dist/runtime/spots/spot-activation-state.d.ts +2 -0
- package/dist/runtime/spots/spot-activation-state.js +1 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +9 -4
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +33 -12
- package/dist/runtime/spots/spot-actor-ingress-admission.d.ts +40 -0
- package/dist/runtime/spots/spot-actor-ingress-admission.js +78 -0
- package/dist/runtime/spots/spot-actor-membership.js +3 -3
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +16 -43
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +56 -113
- package/dist/runtime/spots/spot-actor-packet-drain.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-packet-drain.js +12 -5
- package/dist/runtime/spots/spot-entry-activation.d.ts +4 -3
- package/dist/runtime/spots/spot-entry-activation.js +7 -12
- package/dist/runtime/spots/spot-handler-registry.d.ts +5 -1
- package/dist/runtime/spots/spot-handler-registry.js +31 -15
- package/dist/runtime/spots/spot-manager-public.js +3 -2
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +11 -6
- package/dist/runtime/spots/spot-node-runtime-manager.js +6 -1
- package/dist/runtime/spots/spot-outbound.d.ts +8 -2
- package/dist/runtime/spots/spot-outbound.js +5 -5
- package/dist/runtime/spots/spot-route-packet-dispatch.js +13 -8
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +3 -3
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +9 -5
- package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -2
- package/dist/runtime/spots/spot-serial-executor.d.ts +2 -1
- package/dist/runtime/spots/spot-serial-turn-executor.js +20 -26
- package/dist/runtime/spots/spot-subscription-dispatch.js +5 -2
- package/dist/runtime/spots/spot-timer.d.ts +1 -1
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +11 -3
- package/dist/runtime/streams/actor-session-binding-registry.js +28 -0
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -2
- package/dist/runtime/streams/bound-actor-relay-sender.js +3 -4
- package/dist/runtime/streams/bound-session-service.js +6 -7
- package/dist/runtime/streams/index.d.ts +3 -3
- package/dist/runtime/streams/index.js +22 -2
- package/dist/runtime/streams/managed-stream.js +2 -1
- package/dist/runtime/streams/session-calls.d.ts +1 -1
- package/dist/runtime/streams/session-calls.js +3 -9
- package/dist/runtime/streams/session-context.d.ts +2 -2
- package/dist/runtime/streams/session-context.js +2 -2
- package/dist/runtime/streams/stream-session-runtime.d.ts +1 -0
- package/dist/runtime/streams/stream-session-runtime.js +64 -33
- package/package.json +3 -3
- package/src/contracts/Actors/ZLinkActor.ts +6 -0
- package/src/contracts/Actors/ZLinkSessionBindingIdentity.ts +7 -0
- package/src/contracts/Actors/index.ts +1 -0
- package/src/contracts/Common/CoreTypes.ts +1 -0
- package/src/contracts/Common/HandlerMessageType.ts +50 -0
- package/src/contracts/Common/ZLinkEncodedPayload.ts +13 -25
- package/src/contracts/Common/ZLinkMessage.ts +11 -7
- package/src/contracts/Common/encoded-payload-storage.ts +4 -16
- package/src/contracts/Common/index.ts +1 -1
- package/src/contracts/Common/payload-slab.ts +29 -0
- package/src/contracts/Configuration/RegistrationBuilders.ts +29 -15
- package/src/contracts/Configuration/RegistrationTypes.ts +19 -0
- package/src/contracts/Handlers/Contexts.ts +1 -0
- package/src/contracts/Locations/Authority.ts +7 -1
- package/src/internal.ts +17 -0
- package/src/nest-integration.ts +1 -0
- package/src/runtime/actors/actor-client.ts +257 -163
- package/src/runtime/actors/actor-context.ts +26 -14
- package/src/runtime/actors/actor-execution-context.ts +2 -2
- package/src/runtime/actors/actor-handoff.ts +86 -51
- package/src/runtime/actors/actor-join-deferred-scope.ts +6 -6
- package/src/runtime/actors/actor-local-native-join.ts +38 -17
- package/src/runtime/actors/actor-mailbox.ts +1 -1
- package/src/runtime/actors/actor-remote-joiner.ts +8 -4
- package/src/runtime/actors/actor-routed-join-transport.ts +13 -5
- package/src/runtime/actors/actor-routed-json-request.ts +3 -0
- package/src/runtime/actors/actor-runtime-contracts.ts +4 -2
- package/src/runtime/actors/actor-runtime-state.ts +1 -1
- package/src/runtime/actors/spot-actor-dispatch.ts +70 -68
- package/src/runtime/admission.ts +42 -15
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +4 -0
- package/src/runtime/backend/contracts/index.ts +77 -10
- package/src/runtime/backend/mesh-completion-table.ts +106 -15
- package/src/runtime/backend/mesh-dispatch-pump.ts +294 -146
- package/src/runtime/backend/node/node-backend-adapter-support.ts +42 -32
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +91 -34
- package/src/runtime/backend/node/node-event-loop-poller.ts +14 -5
- package/src/runtime/backend/node/node-mesh-backend-adapter.ts +5 -1
- package/src/runtime/backend/node/node-raw-binding-port.ts +180 -69
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +386 -157
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +56 -11
- package/src/runtime/backend/raw-binding-port.ts +13 -5
- package/src/runtime/channels/channel-clients.ts +26 -11
- package/src/runtime/channels/channel-dispatch-pipeline.ts +77 -65
- package/src/runtime/channels/channel-dispatch-services.ts +7 -12
- package/src/runtime/channels/channel-dispatchers.ts +93 -39
- package/src/runtime/channels/channel-envelope.ts +680 -144
- package/src/runtime/channels/channel-multipart.ts +17 -13
- package/src/runtime/channels/channel-outbound-operations.ts +204 -178
- package/src/runtime/channels/channel-receive-loops.ts +160 -107
- package/src/runtime/channels/channel-runtime-lifecycle.ts +64 -59
- package/src/runtime/channels/channel-runtime-manager.ts +74 -27
- package/src/runtime/channels/channel-socket-registry.ts +20 -5
- package/src/runtime/channels/channel-transports.ts +414 -287
- package/src/runtime/channels/dispatch-error-reporter.ts +4 -9
- package/src/runtime/channels/local-spot-route-transport.ts +27 -29
- package/src/runtime/channels/router-socket-spot-route-transport.ts +63 -32
- package/src/runtime/channels/source-spot-router.ts +75 -38
- package/src/runtime/channels/spot-node-route-transport.ts +67 -37
- package/src/runtime/channels/spot-route-bridge-transport.ts +62 -30
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +105 -34
- package/src/runtime/diagnostics/dispatch-error-details.ts +10 -2
- package/src/runtime/diagnostics/message-flow-bootstrap.ts +6 -0
- package/src/runtime/diagnostics/message-flow-delivery.ts +171 -0
- package/src/runtime/diagnostics/message-flow-record.ts +295 -0
- package/src/runtime/diagnostics/message-flow-worker.ts +146 -0
- package/src/runtime/diagnostics/message-flow.ts +49 -362
- package/src/runtime/diagnostics/runtime-metrics.ts +10 -4
- package/src/runtime/execution/index.ts +6 -0
- package/src/runtime/execution/serial-execution-queue.ts +94 -96
- package/src/runtime/foundation/durable-service-request.ts +212 -89
- package/src/runtime/foundation/operation-registry.ts +287 -38
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +617 -292
- package/src/runtime/foundation/request-runtime.ts +227 -0
- package/src/runtime/foundation/service-discovery-registry.ts +7 -0
- package/src/runtime/foundation/service-liveness-registry.ts +1 -1
- package/src/runtime/foundation/service-mailbox.ts +7 -2
- package/src/runtime/foundation/service-relocation-object-owner.ts +21 -6
- package/src/runtime/foundation/service-runtime-contracts.ts +12 -2
- package/src/runtime/foundation/service-stateful-registry.ts +52 -19
- package/src/runtime/foundation/service-stateful-runtime.ts +365 -198
- package/src/runtime/foundation/service-stateful-wire-codec.ts +18 -0
- package/src/runtime/foundation/service-topology-registry.ts +21 -3
- package/src/runtime/foundation/service-wire-constants.generated.ts +10 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +69 -17
- package/src/runtime/host/actor-packet-relay.ts +160 -156
- package/src/runtime/host/actor-placement-coordinator.ts +1 -1
- package/src/runtime/host/actor-runtime-options-factory.ts +7 -2
- package/src/runtime/host/actor-transfer-runtime.ts +3 -3
- package/src/runtime/host/application-job-queue.ts +56 -27
- package/src/runtime/host/bound-session-relay.ts +0 -1
- package/src/runtime/host/channel-runtime-options-factory.ts +3 -0
- package/src/runtime/host/entry-actor-runtime.ts +14 -6
- package/src/runtime/host/index.ts +388 -113
- package/src/runtime/host/location-runtime-owner.ts +3 -3
- package/src/runtime/host/service-relocation-host-runtime.ts +380 -252
- package/src/runtime/host/spot-address-transport.ts +110 -95
- package/src/runtime/host/spot-runtime-options-factory.ts +3 -0
- package/src/runtime/host/user-spot-creation-coordinator.ts +69 -22
- package/src/runtime/internal-observation.ts +2 -0
- package/src/runtime/locations/actor-location-claims.ts +42 -16
- package/src/runtime/locations/auto-connect-loop.ts +24 -16
- package/src/runtime/locations/auto-connect-planner.ts +2 -5
- package/src/runtime/locations/auto-connect-reconciler.ts +37 -24
- package/src/runtime/locations/in-memory-authority-store.ts +27 -7
- package/src/runtime/locations/in-memory-location-store.ts +1 -74
- package/src/runtime/locations/lifecycle.ts +4 -2
- package/src/runtime/locations/location-store-repository.ts +228 -308
- package/src/runtime/locations/resolvers.ts +20 -8
- package/src/runtime/locations/runtime.ts +16 -28
- package/src/runtime/messaging/creation-payload-codec.ts +12 -10
- package/src/runtime/messaging/framework-json-v1.ts +10 -1
- package/src/runtime/messaging/payload-codec.ts +50 -75
- package/src/runtime/messaging/request-deadline.ts +47 -39
- package/src/runtime/messaging/request-result.ts +88 -17
- package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/index.ts +57 -10
- package/src/runtime/spots/spot-activation-registry.ts +12 -8
- package/src/runtime/spots/spot-activation-state.ts +2 -0
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +62 -37
- package/src/runtime/spots/spot-actor-ingress-admission.ts +157 -0
- package/src/runtime/spots/spot-actor-membership.ts +8 -5
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +122 -206
- package/src/runtime/spots/spot-actor-packet-drain.ts +21 -6
- package/src/runtime/spots/spot-entry-activation.ts +25 -35
- package/src/runtime/spots/spot-handler-registry.ts +72 -15
- package/src/runtime/spots/spot-manager-public.ts +4 -2
- package/src/runtime/spots/spot-node-runtime-manager.ts +16 -7
- package/src/runtime/spots/spot-outbound.ts +26 -10
- package/src/runtime/spots/spot-route-packet-dispatch.ts +18 -8
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +14 -8
- package/src/runtime/spots/spot-runtime-ports.ts +5 -2
- package/src/runtime/spots/spot-serial-executor.ts +1 -1
- package/src/runtime/spots/spot-serial-turn-executor.ts +25 -40
- package/src/runtime/spots/spot-subscription-dispatch.ts +9 -2
- package/src/runtime/spots/spot-timer.ts +1 -1
- package/src/runtime/streams/actor-session-binding-registry.ts +46 -3
- package/src/runtime/streams/bound-actor-relay-sender.ts +16 -5
- package/src/runtime/streams/bound-session-service.ts +10 -7
- package/src/runtime/streams/index.ts +30 -4
- package/src/runtime/streams/managed-stream.ts +2 -1
- package/src/runtime/streams/session-calls.ts +9 -14
- package/src/runtime/streams/session-context.ts +6 -11
- package/src/runtime/streams/stream-session-runtime.ts +79 -40
- package/dist/runtime/spots/spot-lifecycle-metrics.d.ts +0 -8
- package/dist/runtime/spots/spot-lifecycle-metrics.js +0 -17
- package/src/runtime/spots/spot-lifecycle-metrics.ts +0 -16
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { requestTerminalError } from '../messaging/request-deadline';
|
|
2
|
+
import type { PendingOperation } from './operation-registry';
|
|
3
|
+
import type { RequestRuntime } from './request-runtime';
|
|
4
|
+
import { inspectRuntime } from '../internal-observation';
|
|
1
5
|
import { awaitWithAbort, isAbortError } from '../abort';
|
|
2
6
|
import { decodeChannelHeader } from '../channels/channel-envelope';
|
|
3
7
|
import { ZLinkBufferMessage } from '../backend/runtime-message';
|
|
@@ -19,7 +23,7 @@ import {
|
|
|
19
23
|
ZLinkDispatchMessageKind,
|
|
20
24
|
ZLinkRuntimeMessageFlowOutcome as ZLinkMessageFlowOutcome
|
|
21
25
|
} from '../../contracts/Dispatch/ZLinkDispatchOptions';
|
|
22
|
-
import { requestDurableService } from './durable-service-request';
|
|
26
|
+
import { admitServiceRequest, requestDurableService } from './durable-service-request';
|
|
23
27
|
import { shouldCompactBackingArray } from '../admission';
|
|
24
28
|
import { RequestResult, SubmitResult, isZLinkBackendResultError } from '../backend/runtime-values';
|
|
25
29
|
import type { ZLinkDispatchErrorReporter } from '../channels/dispatch-error-reporter';
|
|
@@ -38,7 +42,7 @@ import {
|
|
|
38
42
|
type ActorJoin28
|
|
39
43
|
} from '../protocol/service_wire_pilot_codec.generated';
|
|
40
44
|
import { canonicalActorJoinHandoffId, routingIdBytes } from './actor-join-recovery-codec';
|
|
41
|
-
import { OperationRegistry } from './operation-registry';
|
|
45
|
+
import { OperationCancelledError, OperationRegistry } from './operation-registry';
|
|
42
46
|
import {
|
|
43
47
|
MessageFollowSuppressionRegistry,
|
|
44
48
|
type MessageFollowSuppressionFence
|
|
@@ -119,12 +123,14 @@ import {
|
|
|
119
123
|
SERVICE_WIRE_MAJOR,
|
|
120
124
|
SERVICE_FRAMEWORK_MULTIPART_CONTENT_TYPE
|
|
121
125
|
} from './service-wire-constants.generated';
|
|
126
|
+
import { copyPayloadBytes } from '../../contracts/Common/payload-slab';
|
|
122
127
|
import {
|
|
123
128
|
ServiceWireProtocolError,
|
|
124
129
|
decodeApplicationPayload,
|
|
125
130
|
decodeApplicationPayloadView,
|
|
126
131
|
decodeMultipartApplicationParts,
|
|
127
132
|
encodeApplicationPayload,
|
|
133
|
+
encodeOwnedApplicationPayload,
|
|
128
134
|
type ServiceApplicationPayload
|
|
129
135
|
} from './service-wire-m6a-codec';
|
|
130
136
|
|
|
@@ -163,6 +169,7 @@ interface ServiceSpotMessageFollowState {
|
|
|
163
169
|
export interface ServiceStatefulResult {
|
|
164
170
|
readonly terminalResult: number;
|
|
165
171
|
readonly failureCode: number;
|
|
172
|
+
readonly failureMessage?: string;
|
|
166
173
|
readonly payload?: ServiceApplicationPayload;
|
|
167
174
|
readonly kindData?: ReceiveKindData;
|
|
168
175
|
readonly applicationMetadata?: Buffer;
|
|
@@ -173,7 +180,7 @@ export interface ServiceStatefulResult {
|
|
|
173
180
|
};
|
|
174
181
|
}
|
|
175
182
|
|
|
176
|
-
export interface ServiceStatefulPendingOperation {
|
|
183
|
+
export interface ServiceStatefulPendingOperation extends PendingOperation<ServiceStatefulResult> {
|
|
177
184
|
readonly id: bigint;
|
|
178
185
|
readonly promise: Promise<ServiceStatefulResult>;
|
|
179
186
|
}
|
|
@@ -442,6 +449,28 @@ export interface ServiceUserSpotOperationHandler {
|
|
|
442
449
|
* remain in the common mailbox, where a claimed Spot or Actor owner is serial.
|
|
443
450
|
*/
|
|
444
451
|
export class ServiceStatefulRuntime {
|
|
452
|
+
[inspectRuntime]() {
|
|
453
|
+
return Object.freeze({
|
|
454
|
+
canonicalActorJoinHandoffs: this.canonicalActorJoinHandoffs.size,
|
|
455
|
+
spotRoutes: this.spotRoutes.size,
|
|
456
|
+
instanceRoute: (spotId: string) => {
|
|
457
|
+
const route = this.instanceIntents.get(spotId)?.route;
|
|
458
|
+
return route === undefined ? undefined : Object.freeze({ ...route });
|
|
459
|
+
},
|
|
460
|
+
directSpotRoute: (spotId: string) => {
|
|
461
|
+
const route = this.directSpotRoutes.get(directSpotKey(spotId));
|
|
462
|
+
return route === undefined
|
|
463
|
+
? undefined
|
|
464
|
+
: Object.freeze({ ...route, spot: Object.freeze({ ...route.spot }) });
|
|
465
|
+
},
|
|
466
|
+
spotMessageFollow: Object.freeze(
|
|
467
|
+
[...this.spotMessageFollow.values()].map((state) =>
|
|
468
|
+
Object.freeze({ queuedCount: state.queuedCount, queuedBytes: state.queuedBytes })
|
|
469
|
+
)
|
|
470
|
+
)
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
|
|
445
474
|
// Captured at module load, before any application turn exists: running a
|
|
446
475
|
// callback through this snapshot detaches every AsyncLocalStorage context
|
|
447
476
|
// (Spot serial turn, execution area, flow) so local loopback ingress
|
|
@@ -450,7 +479,7 @@ export class ServiceStatefulRuntime {
|
|
|
450
479
|
|
|
451
480
|
readonly registry: ServiceStatefulRegistry;
|
|
452
481
|
|
|
453
|
-
|
|
482
|
+
readonly operations: ServiceTerminalOperationRegistry<ServiceStatefulResult, bigint>;
|
|
454
483
|
private readonly sessionDeliveries = new Map<string, ServiceSessionDelivery>();
|
|
455
484
|
/**
|
|
456
485
|
* A local Actor owner can replace its own session binding before the
|
|
@@ -494,7 +523,7 @@ export class ServiceStatefulRuntime {
|
|
|
494
523
|
private dispatchErrors?: ZLinkDispatchErrorReporter;
|
|
495
524
|
private sessionOwnerDescriptors?: ServiceSessionOwnerDescriptors;
|
|
496
525
|
private dispatchErrorMeshName?: string;
|
|
497
|
-
|
|
526
|
+
readonly admittedUserSpotOperations = new Map<
|
|
498
527
|
string,
|
|
499
528
|
{
|
|
500
529
|
readonly request: string;
|
|
@@ -517,10 +546,15 @@ export class ServiceStatefulRuntime {
|
|
|
517
546
|
private readonly raw: RawServiceMeshRuntime,
|
|
518
547
|
readonly nodeRid: string,
|
|
519
548
|
readonly nodeGeneration: bigint,
|
|
520
|
-
onPendingOperationsChanged?: () => void
|
|
549
|
+
onPendingOperationsChanged?: () => void,
|
|
550
|
+
private readonly requests?: RequestRuntime
|
|
521
551
|
) {
|
|
522
552
|
this.operations = new ServiceTerminalOperationRegistry(
|
|
523
|
-
|
|
553
|
+
requests?.operations<ServiceStatefulResult, bigint>() ??
|
|
554
|
+
new OperationRegistry(undefined, onPendingOperationsChanged, (reason) =>
|
|
555
|
+
requestTerminalError('Request', reason)
|
|
556
|
+
),
|
|
557
|
+
requests === undefined ? undefined : () => {}
|
|
524
558
|
);
|
|
525
559
|
this.registry = new ServiceStatefulRegistry(nodeRid, nodeGeneration);
|
|
526
560
|
this.registry.createEntrySpot(nodeRid);
|
|
@@ -1519,15 +1553,18 @@ export class ServiceStatefulRuntime {
|
|
|
1519
1553
|
requested: ServiceDirectSpotRouteFence,
|
|
1520
1554
|
payload: ServiceApplicationPayload,
|
|
1521
1555
|
timeoutMs: number,
|
|
1522
|
-
onAdmitted?: () => void
|
|
1556
|
+
onAdmitted?: () => void,
|
|
1557
|
+
requestOperation?: PendingOperation<unknown>,
|
|
1558
|
+
receiver?: import('./operation-registry').OperationObserver<unknown, unknown>
|
|
1523
1559
|
): ServiceStatefulPendingOperation {
|
|
1524
|
-
const pending =
|
|
1560
|
+
const pending =
|
|
1561
|
+
(requestOperation as PendingOperation<ServiceStatefulResult> | undefined) ??
|
|
1562
|
+
this.operations.register(timeoutMs);
|
|
1525
1563
|
const target = this.acceptSpotAuthority(requested);
|
|
1526
1564
|
if (target === undefined) {
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
);
|
|
1565
|
+
const result = internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale);
|
|
1566
|
+
if (receiver === undefined) pending.reply(result);
|
|
1567
|
+
else receiver.operationCompleted(pending.id, result, undefined);
|
|
1531
1568
|
return pending;
|
|
1532
1569
|
}
|
|
1533
1570
|
const header = encodeSpotHeader('spotRequest', sourceSpotId, target, pending.id, {
|
|
@@ -1541,7 +1578,8 @@ export class ServiceStatefulRuntime {
|
|
|
1541
1578
|
timeoutMs,
|
|
1542
1579
|
'spotRequest',
|
|
1543
1580
|
undefined,
|
|
1544
|
-
onAdmitted
|
|
1581
|
+
onAdmitted,
|
|
1582
|
+
receiver
|
|
1545
1583
|
);
|
|
1546
1584
|
return pending;
|
|
1547
1585
|
}
|
|
@@ -1578,16 +1616,20 @@ export class ServiceStatefulRuntime {
|
|
|
1578
1616
|
sourceActor?: ServiceActorRef,
|
|
1579
1617
|
boundSession?: { readonly sessionRid: string; readonly bindingGeneration: bigint },
|
|
1580
1618
|
onAdmitted?: () => void,
|
|
1581
|
-
routeFence?: ServiceActorRouteFence
|
|
1619
|
+
routeFence?: ServiceActorRouteFence,
|
|
1620
|
+
requestOperation?: PendingOperation<unknown>,
|
|
1621
|
+
receiver?: import('./operation-registry').OperationObserver<unknown, unknown>
|
|
1582
1622
|
): ServiceStatefulPendingOperation {
|
|
1583
1623
|
const operationLow = this.nextMessageFollowOperation++;
|
|
1584
|
-
const pending =
|
|
1624
|
+
const pending =
|
|
1625
|
+
(requestOperation as PendingOperation<ServiceStatefulResult> | undefined) ??
|
|
1626
|
+
this.operations.register(timeoutMs, 'registry', operationLow);
|
|
1627
|
+
this.operations.setContext(pending.id, operationLow);
|
|
1585
1628
|
const route = routeFence ?? this.tryActorFence(target);
|
|
1586
1629
|
if (route === undefined) {
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
);
|
|
1630
|
+
const result = internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale);
|
|
1631
|
+
if (receiver !== undefined) receiver.operationCompleted(pending.id, result, undefined);
|
|
1632
|
+
else pending.reply(result);
|
|
1591
1633
|
return pending;
|
|
1592
1634
|
}
|
|
1593
1635
|
const header = encodeActorHeader(
|
|
@@ -1610,7 +1652,8 @@ export class ServiceStatefulRuntime {
|
|
|
1610
1652
|
timeoutMs,
|
|
1611
1653
|
'actorRequest',
|
|
1612
1654
|
undefined,
|
|
1613
|
-
onAdmitted
|
|
1655
|
+
onAdmitted,
|
|
1656
|
+
receiver
|
|
1614
1657
|
);
|
|
1615
1658
|
return pending;
|
|
1616
1659
|
}
|
|
@@ -1712,9 +1755,13 @@ export class ServiceStatefulRuntime {
|
|
|
1712
1755
|
sourceSpotId?: string,
|
|
1713
1756
|
metadataFrame?: Uint8Array,
|
|
1714
1757
|
instanceIntent = false,
|
|
1715
|
-
onAdmitted?: () => void
|
|
1758
|
+
onAdmitted?: () => void,
|
|
1759
|
+
requestOperation?: PendingOperation<unknown>,
|
|
1760
|
+
receiver?: import('./operation-registry').OperationObserver<unknown, unknown>
|
|
1716
1761
|
): ServiceStatefulPendingOperation {
|
|
1717
|
-
const pending =
|
|
1762
|
+
const pending =
|
|
1763
|
+
(requestOperation as PendingOperation<ServiceStatefulResult> | undefined) ??
|
|
1764
|
+
this.operations.register(timeoutMs);
|
|
1718
1765
|
this.submitRequest(
|
|
1719
1766
|
pending,
|
|
1720
1767
|
route.targetNodeRid,
|
|
@@ -1738,7 +1785,8 @@ export class ServiceStatefulRuntime {
|
|
|
1738
1785
|
timeoutMs,
|
|
1739
1786
|
'instanceSpotRequest',
|
|
1740
1787
|
undefined,
|
|
1741
|
-
onAdmitted
|
|
1788
|
+
onAdmitted,
|
|
1789
|
+
receiver
|
|
1742
1790
|
);
|
|
1743
1791
|
return pending;
|
|
1744
1792
|
}
|
|
@@ -1748,7 +1796,8 @@ export class ServiceStatefulRuntime {
|
|
|
1748
1796
|
payload: ServiceApplicationPayload,
|
|
1749
1797
|
timeoutMs: number,
|
|
1750
1798
|
sourceSpotId?: string,
|
|
1751
|
-
metadataFrame?: Uint8Array
|
|
1799
|
+
metadataFrame?: Uint8Array,
|
|
1800
|
+
requestOperation?: PendingOperation<unknown>
|
|
1752
1801
|
): ServiceStatefulPendingOperation {
|
|
1753
1802
|
const deadlineUnixMs = BigInt(Date.now() + timeoutMs);
|
|
1754
1803
|
const payloadFrame = encodeApplicationPayload(payload);
|
|
@@ -1757,7 +1806,9 @@ export class ServiceStatefulRuntime {
|
|
|
1757
1806
|
payloadFrame,
|
|
1758
1807
|
deadlineUnixMs,
|
|
1759
1808
|
sourceSpotId,
|
|
1760
|
-
metadataFrame
|
|
1809
|
+
metadataFrame,
|
|
1810
|
+
undefined,
|
|
1811
|
+
requestOperation
|
|
1761
1812
|
);
|
|
1762
1813
|
}
|
|
1763
1814
|
|
|
@@ -1767,10 +1818,13 @@ export class ServiceStatefulRuntime {
|
|
|
1767
1818
|
deadlineUnixMs: bigint,
|
|
1768
1819
|
sourceSpotId?: string,
|
|
1769
1820
|
metadataFrame?: Uint8Array,
|
|
1770
|
-
onAdmitted?: () => void
|
|
1821
|
+
onAdmitted?: () => void,
|
|
1822
|
+
requestOperation?: PendingOperation<unknown>
|
|
1771
1823
|
): ServiceStatefulPendingOperation {
|
|
1772
1824
|
const timeoutMs = remainingDeadlineMs(deadlineUnixMs);
|
|
1773
|
-
const pending =
|
|
1825
|
+
const pending =
|
|
1826
|
+
(requestOperation as PendingOperation<ServiceStatefulResult> | undefined) ??
|
|
1827
|
+
this.operations.register(timeoutMs);
|
|
1774
1828
|
this.submitRequest(
|
|
1775
1829
|
pending,
|
|
1776
1830
|
target.targetNodeRid,
|
|
@@ -1822,9 +1876,9 @@ export class ServiceStatefulRuntime {
|
|
|
1822
1876
|
queueMicrotask(() => {
|
|
1823
1877
|
try {
|
|
1824
1878
|
this.registry.destroyActor(actor);
|
|
1825
|
-
|
|
1879
|
+
pending.reply({ terminalResult: RequestResult.Ok, failureCode: 0 });
|
|
1826
1880
|
} catch (error) {
|
|
1827
|
-
|
|
1881
|
+
pending.reply(failure(error));
|
|
1828
1882
|
}
|
|
1829
1883
|
});
|
|
1830
1884
|
return pending;
|
|
@@ -1843,10 +1897,7 @@ export class ServiceStatefulRuntime {
|
|
|
1843
1897
|
timeoutMs: number
|
|
1844
1898
|
): ServiceStatefulPendingOperation {
|
|
1845
1899
|
const deadlineMs = performance.now() + timeoutMs;
|
|
1846
|
-
const pending = this.operations.register(
|
|
1847
|
-
timeoutMs,
|
|
1848
|
-
targetNodeRid === this.nodeRid ? 'registry' : 'sender'
|
|
1849
|
-
);
|
|
1900
|
+
const pending = this.operations.register(timeoutMs, 'registry', undefined, deadlineMs);
|
|
1850
1901
|
const target = this.trySpotFence(targetNodeRid, {
|
|
1851
1902
|
...targetSpot,
|
|
1852
1903
|
generation: targetSpotGeneration
|
|
@@ -1866,10 +1917,7 @@ export class ServiceStatefulRuntime {
|
|
|
1866
1917
|
timeoutMs: number
|
|
1867
1918
|
): ServiceStatefulPendingOperation {
|
|
1868
1919
|
const deadlineMs = performance.now() + timeoutMs;
|
|
1869
|
-
const pending = this.operations.register(
|
|
1870
|
-
timeoutMs,
|
|
1871
|
-
targetNodeRid === this.nodeRid ? 'registry' : 'sender'
|
|
1872
|
-
);
|
|
1920
|
+
const pending = this.operations.register(timeoutMs, 'registry', undefined, deadlineMs);
|
|
1873
1921
|
const target = this.trySpotFence(targetNodeRid, {
|
|
1874
1922
|
...targetSpot,
|
|
1875
1923
|
generation: targetSpotGeneration
|
|
@@ -1889,10 +1937,7 @@ export class ServiceStatefulRuntime {
|
|
|
1889
1937
|
timeoutMs: number
|
|
1890
1938
|
): ServiceStatefulPendingOperation {
|
|
1891
1939
|
const deadlineMs = performance.now() + timeoutMs;
|
|
1892
|
-
const pending = this.operations.register(
|
|
1893
|
-
timeoutMs,
|
|
1894
|
-
targetNodeRid === this.nodeRid ? 'registry' : 'sender'
|
|
1895
|
-
);
|
|
1940
|
+
const pending = this.operations.register(timeoutMs, 'registry', undefined, deadlineMs);
|
|
1896
1941
|
this.submitActorJoin(
|
|
1897
1942
|
pending,
|
|
1898
1943
|
actor,
|
|
@@ -1913,10 +1958,7 @@ export class ServiceStatefulRuntime {
|
|
|
1913
1958
|
timeoutMs: number
|
|
1914
1959
|
): ServiceStatefulPendingOperation {
|
|
1915
1960
|
const deadlineMs = performance.now() + timeoutMs;
|
|
1916
|
-
const pending = this.operations.register(
|
|
1917
|
-
timeoutMs,
|
|
1918
|
-
targetNodeRid === this.nodeRid ? 'registry' : 'sender'
|
|
1919
|
-
);
|
|
1961
|
+
const pending = this.operations.register(timeoutMs, 'registry', undefined, deadlineMs);
|
|
1920
1962
|
this.submitActorJoin(
|
|
1921
1963
|
pending,
|
|
1922
1964
|
actor,
|
|
@@ -1951,9 +1993,9 @@ export class ServiceStatefulRuntime {
|
|
|
1951
1993
|
currentMembershipEpoch: transition.currentMembershipEpoch,
|
|
1952
1994
|
resultCode: 0
|
|
1953
1995
|
});
|
|
1954
|
-
|
|
1996
|
+
pending.reply({ terminalResult: RequestResult.Ok, failureCode: 0 });
|
|
1955
1997
|
} catch (error) {
|
|
1956
|
-
|
|
1998
|
+
pending.reply(failure(error));
|
|
1957
1999
|
}
|
|
1958
2000
|
});
|
|
1959
2001
|
return pending;
|
|
@@ -1969,11 +2011,10 @@ export class ServiceStatefulRuntime {
|
|
|
1969
2011
|
close?: () => Promise<void>
|
|
1970
2012
|
): ServiceStatefulPendingOperation {
|
|
1971
2013
|
const deadlineMs = performance.now() + timeoutMs;
|
|
1972
|
-
const pending = this.operations.register(timeoutMs, '
|
|
2014
|
+
const pending = this.operations.register(timeoutMs, 'registry', undefined, deadlineMs);
|
|
1973
2015
|
const sessionOwner = this.localSessionOwner();
|
|
1974
2016
|
if (sessionOwner === undefined) {
|
|
1975
|
-
|
|
1976
|
-
pending.id,
|
|
2017
|
+
pending.reply(
|
|
1977
2018
|
failure(
|
|
1978
2019
|
createInternalFrameworkException(
|
|
1979
2020
|
ZLinkFrameworkInternalErrorKind.RouteNotConnected,
|
|
@@ -2027,7 +2068,7 @@ export class ServiceStatefulRuntime {
|
|
|
2027
2068
|
} else {
|
|
2028
2069
|
this.sessionDeliveries.set(deliveryKey, { ...delivery, binding: previous });
|
|
2029
2070
|
}
|
|
2030
|
-
|
|
2071
|
+
pending.reply({
|
|
2031
2072
|
terminalResult: RequestResult.Ok,
|
|
2032
2073
|
failureCode: 0
|
|
2033
2074
|
});
|
|
@@ -2036,7 +2077,7 @@ export class ServiceStatefulRuntime {
|
|
|
2036
2077
|
const binding = this.registry.installSessionBinding(localBinding);
|
|
2037
2078
|
installedDelivery = { ...delivery, binding };
|
|
2038
2079
|
this.sessionDeliveries.set(deliveryKey, installedDelivery);
|
|
2039
|
-
|
|
2080
|
+
pending.reply({
|
|
2040
2081
|
terminalResult: RequestResult.Ok,
|
|
2041
2082
|
failureCode: 0,
|
|
2042
2083
|
kindData: undefined
|
|
@@ -2065,7 +2106,7 @@ export class ServiceStatefulRuntime {
|
|
|
2065
2106
|
) {
|
|
2066
2107
|
this.sessionDeliveries.delete(deliveryKey);
|
|
2067
2108
|
}
|
|
2068
|
-
|
|
2109
|
+
pending.reply(failure(error));
|
|
2069
2110
|
}
|
|
2070
2111
|
return pending;
|
|
2071
2112
|
}
|
|
@@ -2079,7 +2120,7 @@ export class ServiceStatefulRuntime {
|
|
|
2079
2120
|
generation
|
|
2080
2121
|
});
|
|
2081
2122
|
} catch (error) {
|
|
2082
|
-
|
|
2123
|
+
pending.replyFailure(error);
|
|
2083
2124
|
return pending;
|
|
2084
2125
|
}
|
|
2085
2126
|
void this.requestDurableOperation(
|
|
@@ -2087,13 +2128,12 @@ export class ServiceStatefulRuntime {
|
|
|
2087
2128
|
[header],
|
|
2088
2129
|
pending.id,
|
|
2089
2130
|
'streamBind',
|
|
2090
|
-
|
|
2131
|
+
pending
|
|
2091
2132
|
).then(
|
|
2092
2133
|
(reply) => this.completeRemoteReply(pending, actor.nodeRid, 'streamBind', undefined, reply),
|
|
2093
|
-
(error) =>
|
|
2134
|
+
(error) => pending.replyFailure(error)
|
|
2094
2135
|
);
|
|
2095
|
-
return {
|
|
2096
|
-
id: pending.id,
|
|
2136
|
+
return Object.assign(Object.create(pending) as ServiceStatefulPendingOperation, {
|
|
2097
2137
|
promise: pending.promise.then((result) => {
|
|
2098
2138
|
if (result.terminalResult === RequestResult.Ok && result.streamBinding !== undefined) {
|
|
2099
2139
|
const committed: ServiceSessionDelivery = {
|
|
@@ -2125,7 +2165,7 @@ export class ServiceStatefulRuntime {
|
|
|
2125
2165
|
}
|
|
2126
2166
|
return result;
|
|
2127
2167
|
})
|
|
2128
|
-
};
|
|
2168
|
+
});
|
|
2129
2169
|
}
|
|
2130
2170
|
|
|
2131
2171
|
closeBoundSession(
|
|
@@ -2136,8 +2176,7 @@ export class ServiceStatefulRuntime {
|
|
|
2136
2176
|
const pending = this.operations.register(timeoutMs);
|
|
2137
2177
|
const binding = this.registry.binding(actor);
|
|
2138
2178
|
if (binding === undefined) {
|
|
2139
|
-
|
|
2140
|
-
pending.id,
|
|
2179
|
+
pending.reply(
|
|
2141
2180
|
internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorSessionNotBound)
|
|
2142
2181
|
);
|
|
2143
2182
|
return pending;
|
|
@@ -2165,8 +2204,14 @@ export class ServiceStatefulRuntime {
|
|
|
2165
2204
|
)[0]!
|
|
2166
2205
|
);
|
|
2167
2206
|
const reply = routingIdsEqual(binding.sessionOwnerNodeRid, this.nodeRid)
|
|
2168
|
-
? this.requestLocalInfrastructure(header, pending.id,
|
|
2169
|
-
:
|
|
2207
|
+
? this.requestLocalInfrastructure(header, pending.id, pending)
|
|
2208
|
+
: requestDurableService(
|
|
2209
|
+
this.raw,
|
|
2210
|
+
binding.sessionOwnerNodeRid,
|
|
2211
|
+
[header],
|
|
2212
|
+
pending,
|
|
2213
|
+
'boundSessionClose'
|
|
2214
|
+
);
|
|
2170
2215
|
void reply.then(
|
|
2171
2216
|
(parts) =>
|
|
2172
2217
|
this.completeRemoteReply(
|
|
@@ -2176,7 +2221,7 @@ export class ServiceStatefulRuntime {
|
|
|
2176
2221
|
undefined,
|
|
2177
2222
|
parts
|
|
2178
2223
|
),
|
|
2179
|
-
(error) =>
|
|
2224
|
+
(error) => pending.replyFailure(error)
|
|
2180
2225
|
);
|
|
2181
2226
|
return pending;
|
|
2182
2227
|
}
|
|
@@ -2194,19 +2239,16 @@ export class ServiceStatefulRuntime {
|
|
|
2194
2239
|
!routingIdsEqual(delivery.binding.sessionRid, sessionRid) ||
|
|
2195
2240
|
delivery.binding.bindingGeneration !== expectedBindingGeneration
|
|
2196
2241
|
) {
|
|
2197
|
-
|
|
2198
|
-
pending.id,
|
|
2199
|
-
internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale)
|
|
2200
|
-
);
|
|
2242
|
+
pending.reply(internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale));
|
|
2201
2243
|
return pending;
|
|
2202
2244
|
}
|
|
2203
2245
|
this.sessionDeliveries.delete(actorKey(actor));
|
|
2204
2246
|
if (actor.nodeRid === this.nodeRid) {
|
|
2205
2247
|
try {
|
|
2206
2248
|
this.registry.unbindSession(actor, expectedBindingGeneration);
|
|
2207
|
-
|
|
2249
|
+
pending.reply({ terminalResult: RequestResult.Ok, failureCode: 0 });
|
|
2208
2250
|
} catch (error) {
|
|
2209
|
-
|
|
2251
|
+
pending.reply(failure(error));
|
|
2210
2252
|
}
|
|
2211
2253
|
return pending;
|
|
2212
2254
|
}
|
|
@@ -2278,7 +2320,9 @@ export class ServiceStatefulRuntime {
|
|
|
2278
2320
|
}
|
|
2279
2321
|
|
|
2280
2322
|
expireOperations(nowMs: number, turnDeadlineMs: number): number {
|
|
2281
|
-
return this.operations.
|
|
2323
|
+
return this.requests === undefined && nowMs >= this.operations.nextDeadlineMs()
|
|
2324
|
+
? this.operations.expire(nowMs, turnDeadlineMs)
|
|
2325
|
+
: 0;
|
|
2282
2326
|
}
|
|
2283
2327
|
|
|
2284
2328
|
get pendingOperationCount(): number {
|
|
@@ -2287,7 +2331,7 @@ export class ServiceStatefulRuntime {
|
|
|
2287
2331
|
|
|
2288
2332
|
/** The next stateful request expiry, as a lower bound. */
|
|
2289
2333
|
nextMaintenanceDeadlineMs(): number {
|
|
2290
|
-
return this.operations.nextDeadlineMs();
|
|
2334
|
+
return this.requests === undefined ? this.operations.nextDeadlineMs() : Infinity;
|
|
2291
2335
|
}
|
|
2292
2336
|
|
|
2293
2337
|
close(): void {
|
|
@@ -2396,7 +2440,7 @@ export class ServiceStatefulRuntime {
|
|
|
2396
2440
|
? record.parts.length >= 2
|
|
2397
2441
|
? record.parts[record.parts.length - 1]
|
|
2398
2442
|
: undefined
|
|
2399
|
-
:
|
|
2443
|
+
: encodeOwnedApplicationPayload(canonicalPayload);
|
|
2400
2444
|
try {
|
|
2401
2445
|
return await this.handleIngress(
|
|
2402
2446
|
record,
|
|
@@ -2462,7 +2506,7 @@ export class ServiceStatefulRuntime {
|
|
|
2462
2506
|
}
|
|
2463
2507
|
}
|
|
2464
2508
|
|
|
2465
|
-
|
|
2509
|
+
async handleIngress(
|
|
2466
2510
|
ingress: RawServiceIngressRecord,
|
|
2467
2511
|
record: ServiceStatefulWireRecord,
|
|
2468
2512
|
payloadFrame: Buffer | undefined,
|
|
@@ -2555,6 +2599,62 @@ export class ServiceStatefulRuntime {
|
|
|
2555
2599
|
) {
|
|
2556
2600
|
throw new ServiceStaleGenerationError('binding', record.target.actor.actorId);
|
|
2557
2601
|
}
|
|
2602
|
+
if (
|
|
2603
|
+
!this.registry.acceptBoundSessionSequence(
|
|
2604
|
+
record.target.actor,
|
|
2605
|
+
record.boundSession.bindingGeneration,
|
|
2606
|
+
record.boundSession.sequence
|
|
2607
|
+
)
|
|
2608
|
+
) {
|
|
2609
|
+
const error = new ZLinkFrameworkException(
|
|
2610
|
+
ZLinkFrameworkErrorKind.InvalidOperation,
|
|
2611
|
+
'Bound Session relay sequence does not increase.'
|
|
2612
|
+
);
|
|
2613
|
+
const reporter = this.dispatchErrors;
|
|
2614
|
+
if (record.kind === 'actorRequest') {
|
|
2615
|
+
if (reporter?.captureEnabled() === true) {
|
|
2616
|
+
reporter.report({
|
|
2617
|
+
surface: ZLinkDispatchErrorSurface.StreamSession,
|
|
2618
|
+
messageKind: ZLinkDispatchMessageKind.Request,
|
|
2619
|
+
reason: ZLinkDispatchErrorReason.StaleTarget,
|
|
2620
|
+
action: ZLinkDispatchErrorAction.ReplyError,
|
|
2621
|
+
meshName: this.dispatchErrorMeshName,
|
|
2622
|
+
sourceRid: ingress.sourceRoutingId,
|
|
2623
|
+
actorId: record.target.actor.actorId,
|
|
2624
|
+
correlationId: record.correlation?.toString(),
|
|
2625
|
+
error
|
|
2626
|
+
});
|
|
2627
|
+
}
|
|
2628
|
+
const result = failure(error);
|
|
2629
|
+
this.replyWire(
|
|
2630
|
+
ingress,
|
|
2631
|
+
record.correlation!,
|
|
2632
|
+
result.terminalResult,
|
|
2633
|
+
result.failureCode
|
|
2634
|
+
);
|
|
2635
|
+
return 'infrastructure';
|
|
2636
|
+
}
|
|
2637
|
+
const tracePoint = flowIfEnabled(reporter?.flow, ZLinkMessageFlowOutcome.Dropped);
|
|
2638
|
+
if (tracePoint !== undefined) {
|
|
2639
|
+
tracePoint.trace({
|
|
2640
|
+
outcome: ZLinkMessageFlowOutcome.Dropped,
|
|
2641
|
+
surface: ZLinkDispatchErrorSurface.StreamSession,
|
|
2642
|
+
messageKind: ZLinkDispatchMessageKind.Send,
|
|
2643
|
+
packetName: decodeApplicationPayloadView(payloadFrame!).packetName,
|
|
2644
|
+
...(this.dispatchErrorMeshName === undefined
|
|
2645
|
+
? {}
|
|
2646
|
+
: { meshName: this.dispatchErrorMeshName }),
|
|
2647
|
+
...(record.correlation === undefined
|
|
2648
|
+
? {}
|
|
2649
|
+
: { correlationId: record.correlation.toString() }),
|
|
2650
|
+
sourceRid: ingress.sourceRoutingId,
|
|
2651
|
+
actorId: record.target.actor.actorId,
|
|
2652
|
+
streamSessionId: record.boundSession.sessionRid,
|
|
2653
|
+
errorReason: ZLinkDispatchErrorReason.StaleTarget
|
|
2654
|
+
});
|
|
2655
|
+
}
|
|
2656
|
+
return 'application';
|
|
2657
|
+
}
|
|
2558
2658
|
}
|
|
2559
2659
|
return this.enqueueApplicationFrame(
|
|
2560
2660
|
ingress,
|
|
@@ -2714,7 +2814,7 @@ export class ServiceStatefulRuntime {
|
|
|
2714
2814
|
return !lifecycle.isMaterialized(applicationTarget);
|
|
2715
2815
|
}
|
|
2716
2816
|
|
|
2717
|
-
|
|
2817
|
+
enqueueActivatedInstanceSpot(
|
|
2718
2818
|
ingress: RawServiceIngressRecord,
|
|
2719
2819
|
record: Extract<ServiceStatefulWireRecord, { readonly kind: 'instanceSpot' }>,
|
|
2720
2820
|
payloadFrame: Buffer,
|
|
@@ -2795,7 +2895,7 @@ export class ServiceStatefulRuntime {
|
|
|
2795
2895
|
return result;
|
|
2796
2896
|
}
|
|
2797
2897
|
|
|
2798
|
-
|
|
2898
|
+
async continueMissingInstanceActivation(
|
|
2799
2899
|
ingress: RawServiceIngressRecord,
|
|
2800
2900
|
record: Extract<
|
|
2801
2901
|
ServiceStatefulWireRecord,
|
|
@@ -2894,7 +2994,7 @@ export class ServiceStatefulRuntime {
|
|
|
2894
2994
|
* record only of a message whose handler turn started before it; a message queued
|
|
2895
2995
|
* behind that Close is not counted, so it cannot hold the Close it follows.
|
|
2896
2996
|
*/
|
|
2897
|
-
|
|
2997
|
+
activationTerminalCompletion(
|
|
2898
2998
|
target: ServiceInstanceActivationTarget,
|
|
2899
2999
|
route: ServiceInstanceRouteFence
|
|
2900
3000
|
): {
|
|
@@ -2941,7 +3041,7 @@ export class ServiceStatefulRuntime {
|
|
|
2941
3041
|
return { onTerminalCompletion, onHandlerTurnStarted };
|
|
2942
3042
|
}
|
|
2943
3043
|
|
|
2944
|
-
|
|
3044
|
+
instanceApplicationTerminalCompletion(
|
|
2945
3045
|
target: ServiceInstanceApplicationTarget
|
|
2946
3046
|
): (() => Promise<void>) | undefined {
|
|
2947
3047
|
const lifecycle = this.instanceApplicationLifecycle;
|
|
@@ -3011,7 +3111,7 @@ export class ServiceStatefulRuntime {
|
|
|
3011
3111
|
for (const waiter of waiters) waiter();
|
|
3012
3112
|
}
|
|
3013
3113
|
|
|
3014
|
-
|
|
3114
|
+
finishMissingInstanceActivationFailure(
|
|
3015
3115
|
ingress: RawServiceIngressRecord,
|
|
3016
3116
|
record: Extract<
|
|
3017
3117
|
ServiceStatefulWireRecord,
|
|
@@ -3179,7 +3279,7 @@ export class ServiceStatefulRuntime {
|
|
|
3179
3279
|
return { intent, route: current };
|
|
3180
3280
|
}
|
|
3181
3281
|
|
|
3182
|
-
|
|
3282
|
+
validateInstanceIngress(
|
|
3183
3283
|
ingress: RawServiceIngressRecord,
|
|
3184
3284
|
record: Extract<ServiceStatefulWireRecord, { readonly kind: 'instanceSpot' }>
|
|
3185
3285
|
): void {
|
|
@@ -3281,7 +3381,7 @@ export class ServiceStatefulRuntime {
|
|
|
3281
3381
|
: undefined;
|
|
3282
3382
|
}
|
|
3283
3383
|
|
|
3284
|
-
|
|
3384
|
+
activateMissingInstanceAsync(
|
|
3285
3385
|
record: Extract<
|
|
3286
3386
|
ServiceStatefulWireRecord,
|
|
3287
3387
|
{ readonly kind: 'instanceSpot'; readonly activation: 'missing' }
|
|
@@ -3352,7 +3452,7 @@ export class ServiceStatefulRuntime {
|
|
|
3352
3452
|
return operation;
|
|
3353
3453
|
}
|
|
3354
3454
|
|
|
3355
|
-
|
|
3455
|
+
async runMissingInstanceActivation(
|
|
3356
3456
|
record: Extract<
|
|
3357
3457
|
ServiceStatefulWireRecord,
|
|
3358
3458
|
{ readonly kind: 'instanceSpot'; readonly activation: 'missing' }
|
|
@@ -3716,7 +3816,7 @@ export class ServiceStatefulRuntime {
|
|
|
3716
3816
|
}
|
|
3717
3817
|
})
|
|
3718
3818
|
};
|
|
3719
|
-
const applicationFrame = payloadFrame ??
|
|
3819
|
+
const applicationFrame = payloadFrame ?? encodeOwnedApplicationPayload(emptyPayload());
|
|
3720
3820
|
return this.enqueueLifecycleFrame(
|
|
3721
3821
|
ingress,
|
|
3722
3822
|
`spot:${record.target.spot.spotId}`,
|
|
@@ -4218,7 +4318,7 @@ export class ServiceStatefulRuntime {
|
|
|
4218
4318
|
);
|
|
4219
4319
|
}
|
|
4220
4320
|
|
|
4221
|
-
|
|
4321
|
+
enqueueApplicationFrame(
|
|
4222
4322
|
ingress: RawServiceIngressRecord,
|
|
4223
4323
|
owner: string,
|
|
4224
4324
|
payloadFrame: Buffer,
|
|
@@ -4302,7 +4402,7 @@ export class ServiceStatefulRuntime {
|
|
|
4302
4402
|
channelName,
|
|
4303
4403
|
topic,
|
|
4304
4404
|
sourceSpotId,
|
|
4305
|
-
|
|
4405
|
+
encodeOwnedApplicationPayload(payload),
|
|
4306
4406
|
sourceNodeRid,
|
|
4307
4407
|
applicationJobOwner
|
|
4308
4408
|
);
|
|
@@ -4644,34 +4744,52 @@ export class ServiceStatefulRuntime {
|
|
|
4644
4744
|
operationKind: 'userSpotCreate' | 'userSpotClose' | 'actorCreate',
|
|
4645
4745
|
timeoutMs: number
|
|
4646
4746
|
): Promise<ServiceUserSpotOperationResult> {
|
|
4647
|
-
const
|
|
4747
|
+
const deadlineMs = performance.now() + Math.max(1, timeoutMs);
|
|
4748
|
+
const pending = this.operations.register(
|
|
4749
|
+
Math.max(1, timeoutMs),
|
|
4750
|
+
'registry',
|
|
4751
|
+
undefined,
|
|
4752
|
+
deadlineMs
|
|
4753
|
+
);
|
|
4754
|
+
const completed = (parts: readonly Buffer[]) => {
|
|
4755
|
+
try {
|
|
4756
|
+
if (parts.length < 1 || parts.length > 2) {
|
|
4757
|
+
throw new ServiceWireProtocolError('Invalid creation operation reply parts.');
|
|
4758
|
+
}
|
|
4759
|
+
const decoded = decodeStatefulReply(
|
|
4760
|
+
parts[0]!,
|
|
4761
|
+
correlation,
|
|
4762
|
+
operationKind,
|
|
4763
|
+
parts.length >= 2
|
|
4764
|
+
);
|
|
4765
|
+
if (decoded.terminalResult !== RequestResult.Ok && parts.length !== 1) {
|
|
4766
|
+
throw new ServiceWireProtocolError('Failed creation operation reply carries a payload.');
|
|
4767
|
+
}
|
|
4768
|
+
if (operationKind === 'userSpotClose' && parts.length !== 1) {
|
|
4769
|
+
throw new ServiceWireProtocolError('User Spot close reply carries a payload.');
|
|
4770
|
+
}
|
|
4771
|
+
const value: ServiceUserSpotOperationResult = {
|
|
4772
|
+
terminalResult: decoded.terminalResult,
|
|
4773
|
+
failureCode: decoded.failureCode,
|
|
4774
|
+
...(decoded.tail === undefined ? {} : { tail: decoded.tail as never }),
|
|
4775
|
+
...(parts.length === 2 ? { payload: decodeApplicationPayload(parts[1]!) } : {})
|
|
4776
|
+
};
|
|
4777
|
+
pending.complete(value);
|
|
4778
|
+
} catch (error) {
|
|
4779
|
+
pending.fail(translateWireReplyDecodeError(error));
|
|
4780
|
+
}
|
|
4781
|
+
};
|
|
4782
|
+
const failed = (error: unknown) => {
|
|
4783
|
+
pending.fail(error);
|
|
4784
|
+
};
|
|
4785
|
+
void this.requestDurableOperation(
|
|
4648
4786
|
targetNodeRid,
|
|
4649
4787
|
[header],
|
|
4650
4788
|
correlation,
|
|
4651
4789
|
operationKind,
|
|
4652
|
-
|
|
4653
|
-
);
|
|
4654
|
-
|
|
4655
|
-
try {
|
|
4656
|
-
if (parts.length < 1 || parts.length > 2) {
|
|
4657
|
-
throw new ServiceWireProtocolError('Invalid creation operation reply parts.');
|
|
4658
|
-
}
|
|
4659
|
-
const decoded = decodeStatefulReply(parts[0]!, correlation, operationKind, parts.length >= 2);
|
|
4660
|
-
if (decoded.terminalResult !== RequestResult.Ok && parts.length !== 1) {
|
|
4661
|
-
throw new ServiceWireProtocolError('Failed creation operation reply carries a payload.');
|
|
4662
|
-
}
|
|
4663
|
-
if (operationKind === 'userSpotClose' && parts.length !== 1) {
|
|
4664
|
-
throw new ServiceWireProtocolError('User Spot close reply carries a payload.');
|
|
4665
|
-
}
|
|
4666
|
-
return {
|
|
4667
|
-
terminalResult: decoded.terminalResult,
|
|
4668
|
-
failureCode: decoded.failureCode,
|
|
4669
|
-
...(decoded.tail === undefined ? {} : { tail: decoded.tail as never }),
|
|
4670
|
-
...(parts.length === 2 ? { payload: decodeApplicationPayload(parts[1]!) } : {})
|
|
4671
|
-
};
|
|
4672
|
-
} catch (error) {
|
|
4673
|
-
throw translateWireReplyDecodeError(error);
|
|
4674
|
-
}
|
|
4790
|
+
pending
|
|
4791
|
+
).then(completed, failed);
|
|
4792
|
+
return pending.promise;
|
|
4675
4793
|
}
|
|
4676
4794
|
|
|
4677
4795
|
private async requestDurableOperation(
|
|
@@ -4679,44 +4797,31 @@ export class ServiceStatefulRuntime {
|
|
|
4679
4797
|
parts: readonly Buffer[],
|
|
4680
4798
|
correlation: bigint,
|
|
4681
4799
|
operationKind: 'userSpotCreate' | 'userSpotClose' | 'actorCreate' | 'streamBind' | 'actorJoin',
|
|
4682
|
-
|
|
4800
|
+
pending: PendingOperation<unknown>
|
|
4683
4801
|
): Promise<readonly Buffer[]> {
|
|
4684
4802
|
this.requireOpen();
|
|
4685
4803
|
if (targetNodeRid === this.nodeRid) {
|
|
4686
|
-
return this.requestLocalInfrastructure(
|
|
4687
|
-
parts[0]!,
|
|
4688
|
-
correlation,
|
|
4689
|
-
Math.ceil(deadlineMs - performance.now())
|
|
4690
|
-
);
|
|
4804
|
+
return this.requestLocalInfrastructure(parts[0]!, correlation, pending);
|
|
4691
4805
|
}
|
|
4692
|
-
return requestDurableService(this.raw, targetNodeRid, parts,
|
|
4806
|
+
return requestDurableService(this.raw, targetNodeRid, parts, pending, operationKind);
|
|
4693
4807
|
}
|
|
4694
4808
|
|
|
4695
4809
|
private requestLocalInfrastructure(
|
|
4696
4810
|
header: Buffer,
|
|
4697
4811
|
requestSequence: bigint,
|
|
4698
|
-
|
|
4812
|
+
pending: PendingOperation<unknown>
|
|
4699
4813
|
): Promise<readonly Buffer[]> {
|
|
4700
4814
|
return new Promise((resolve, reject) => {
|
|
4701
|
-
|
|
4702
|
-
const fail = (error: unknown) => {
|
|
4703
|
-
if (settled) return;
|
|
4704
|
-
settled = true;
|
|
4705
|
-
clearTimeout(timer);
|
|
4706
|
-
reject(error);
|
|
4707
|
-
};
|
|
4708
|
-
const timer = setTimeout(() => {
|
|
4709
|
-
fail(new Error('Local infrastructure request timed out.'));
|
|
4710
|
-
}, timeoutMs);
|
|
4711
|
-
const finish = (parts: readonly Uint8Array[]) => {
|
|
4712
|
-
if (settled) return;
|
|
4713
|
-
settled = true;
|
|
4714
|
-
clearTimeout(timer);
|
|
4815
|
+
const finish: NonNullable<ServiceMailboxRecord['reply']> = (parts) => {
|
|
4715
4816
|
resolve(parts.map((part) => Buffer.from(part)));
|
|
4716
4817
|
};
|
|
4717
4818
|
void (async () => {
|
|
4718
4819
|
const applicationJobOwner = await this.raw.reserveLocalIngress();
|
|
4719
4820
|
try {
|
|
4821
|
+
if (!pending.isPending()) {
|
|
4822
|
+
await pending.promise;
|
|
4823
|
+
throw new OperationCancelledError(pending.id, 'Request is already terminal.');
|
|
4824
|
+
}
|
|
4720
4825
|
const result = await this.ingress({
|
|
4721
4826
|
command: header[SERVICE_WIRE_COMMAND_OFFSET]!,
|
|
4722
4827
|
flags: header[SERVICE_WIRE_FLAGS_OFFSET]!,
|
|
@@ -4727,22 +4832,21 @@ export class ServiceStatefulRuntime {
|
|
|
4727
4832
|
applicationJobOwner
|
|
4728
4833
|
});
|
|
4729
4834
|
if (result !== 'infrastructure') {
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
`Local infrastructure request was rejected as '${result ?? 'unsupported'}'.`
|
|
4733
|
-
)
|
|
4835
|
+
throw new ServiceWireProtocolError(
|
|
4836
|
+
`Local infrastructure request was rejected as '${result ?? 'unsupported'}'.`
|
|
4734
4837
|
);
|
|
4735
4838
|
}
|
|
4736
4839
|
} finally {
|
|
4737
4840
|
applicationJobOwner.close();
|
|
4738
4841
|
}
|
|
4739
|
-
})().catch(
|
|
4842
|
+
})().catch(reject);
|
|
4740
4843
|
});
|
|
4741
4844
|
}
|
|
4742
4845
|
|
|
4743
4846
|
private async submitOneWay(targetNodeRid: string, parts: readonly Buffer[]): Promise<number> {
|
|
4744
4847
|
this.requireOpen();
|
|
4745
4848
|
if (targetNodeRid === this.nodeRid) {
|
|
4849
|
+
parts = copyRetainedServiceFrames(parts);
|
|
4746
4850
|
const applicationJobOwner = await this.raw.reserveLocalIngress();
|
|
4747
4851
|
if (captureZLinkExecutionTurn() !== undefined) {
|
|
4748
4852
|
// The sender is inside a Spot serial turn. Running ingress inline
|
|
@@ -4814,9 +4918,11 @@ export class ServiceStatefulRuntime {
|
|
|
4814
4918
|
| 'streamUnbind'
|
|
4815
4919
|
| 'instanceSpotRequest',
|
|
4816
4920
|
actor?: ServiceActorRef,
|
|
4817
|
-
onAdmitted?: () => void
|
|
4921
|
+
onAdmitted?: () => void,
|
|
4922
|
+
receiver?: import('./operation-registry').OperationObserver<unknown, unknown>
|
|
4818
4923
|
): void {
|
|
4819
4924
|
if (targetNodeRid === this.nodeRid) {
|
|
4925
|
+
parts = copyRetainedServiceFrames(parts);
|
|
4820
4926
|
const deadlineUnixMs = BigInt(Date.now() + Math.max(0, timeoutMs));
|
|
4821
4927
|
const capacityStop = new AbortController();
|
|
4822
4928
|
void pending.promise.then(
|
|
@@ -4826,7 +4932,7 @@ export class ServiceStatefulRuntime {
|
|
|
4826
4932
|
void (async () => {
|
|
4827
4933
|
const applicationJobOwner = await this.raw.reserveLocalIngress(capacityStop.signal);
|
|
4828
4934
|
try {
|
|
4829
|
-
if (!
|
|
4935
|
+
if (!pending.isPending()) return;
|
|
4830
4936
|
const localIngress: RawServiceIngressRecord = {
|
|
4831
4937
|
command: parts[0]![SERVICE_WIRE_COMMAND_OFFSET]!,
|
|
4832
4938
|
flags: parts[0]![SERVICE_WIRE_FLAGS_OFFSET]!,
|
|
@@ -4841,19 +4947,71 @@ export class ServiceStatefulRuntime {
|
|
|
4841
4947
|
pending,
|
|
4842
4948
|
operationKind,
|
|
4843
4949
|
actor,
|
|
4844
|
-
deadlineUnixMs
|
|
4950
|
+
deadlineUnixMs,
|
|
4951
|
+
receiver
|
|
4845
4952
|
);
|
|
4846
4953
|
} catch (error) {
|
|
4847
|
-
|
|
4954
|
+
receiver === undefined
|
|
4955
|
+
? pending.reply(failure(error))
|
|
4956
|
+
: receiver.operationFailed(pending.id, error, undefined);
|
|
4848
4957
|
} finally {
|
|
4849
4958
|
applicationJobOwner.close();
|
|
4850
4959
|
}
|
|
4851
|
-
})().catch((error) =>
|
|
4960
|
+
})().catch((error) =>
|
|
4961
|
+
receiver === undefined
|
|
4962
|
+
? pending.reply(failure(error))
|
|
4963
|
+
: receiver.operationFailed(pending.id, error, undefined)
|
|
4964
|
+
);
|
|
4852
4965
|
return;
|
|
4853
4966
|
}
|
|
4854
|
-
|
|
4967
|
+
if (receiver !== undefined) {
|
|
4968
|
+
const completion = {
|
|
4969
|
+
operationCompleted: (_id: bigint, reply: readonly Buffer[]) =>
|
|
4970
|
+
this.completeRemoteReply(pending, targetNodeRid, operationKind, actor, reply, receiver),
|
|
4971
|
+
operationFailed: (_id: bigint, error: unknown) =>
|
|
4972
|
+
receiver.operationFailed(pending.id, error, undefined)
|
|
4973
|
+
};
|
|
4974
|
+
if (this.raw.isPeerRouteReady(targetNodeRid) === true) {
|
|
4975
|
+
this.raw.requestService(targetNodeRid, parts, timeoutMs, onAdmitted, pending, completion);
|
|
4976
|
+
return;
|
|
4977
|
+
}
|
|
4978
|
+
admitServiceRequest(
|
|
4979
|
+
this.raw,
|
|
4980
|
+
targetNodeRid,
|
|
4981
|
+
pending,
|
|
4982
|
+
(remaining, finished) => {
|
|
4983
|
+
this.raw.requestService(targetNodeRid, parts, remaining, onAdmitted, pending, {
|
|
4984
|
+
operationCompleted: (id, reply) => {
|
|
4985
|
+
finished();
|
|
4986
|
+
completion.operationCompleted(id, reply);
|
|
4987
|
+
},
|
|
4988
|
+
operationFailed: (id, error) => {
|
|
4989
|
+
finished();
|
|
4990
|
+
completion.operationFailed(id, error);
|
|
4991
|
+
}
|
|
4992
|
+
});
|
|
4993
|
+
},
|
|
4994
|
+
(error) => completion.operationFailed(pending.id, error),
|
|
4995
|
+
operationKind
|
|
4996
|
+
);
|
|
4997
|
+
return;
|
|
4998
|
+
}
|
|
4999
|
+
const reply =
|
|
5000
|
+
this.raw.isPeerRouteReady(targetNodeRid) === true
|
|
5001
|
+
? this.raw.requestService(targetNodeRid, parts, timeoutMs, onAdmitted, pending)
|
|
5002
|
+
: requestDurableService(
|
|
5003
|
+
this.raw,
|
|
5004
|
+
targetNodeRid,
|
|
5005
|
+
parts,
|
|
5006
|
+
pending,
|
|
5007
|
+
operationKind,
|
|
5008
|
+
undefined,
|
|
5009
|
+
undefined,
|
|
5010
|
+
onAdmitted
|
|
5011
|
+
);
|
|
5012
|
+
void reply.then(
|
|
4855
5013
|
(reply) => this.completeRemoteReply(pending, targetNodeRid, operationKind, actor, reply),
|
|
4856
|
-
(error) =>
|
|
5014
|
+
(error) => pending.replyFailure(error)
|
|
4857
5015
|
);
|
|
4858
5016
|
}
|
|
4859
5017
|
|
|
@@ -4871,10 +5029,7 @@ export class ServiceStatefulRuntime {
|
|
|
4871
5029
|
? this.tryActorFence(actor)
|
|
4872
5030
|
: this.acceptCanonicalActorFence(actor, canonical.actorFence);
|
|
4873
5031
|
if (target === undefined || actorRoute === undefined) {
|
|
4874
|
-
|
|
4875
|
-
pending.id,
|
|
4876
|
-
internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale)
|
|
4877
|
-
);
|
|
5032
|
+
pending.reply(internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale));
|
|
4878
5033
|
return;
|
|
4879
5034
|
}
|
|
4880
5035
|
if (canonical !== undefined) {
|
|
@@ -4914,7 +5069,7 @@ export class ServiceStatefulRuntime {
|
|
|
4914
5069
|
}).map((frame) => Buffer.from(frame));
|
|
4915
5070
|
} catch (error) {
|
|
4916
5071
|
this.canonicalActorJoinHandoffs.delete(pending.id);
|
|
4917
|
-
|
|
5072
|
+
pending.replyFailure(error);
|
|
4918
5073
|
return;
|
|
4919
5074
|
}
|
|
4920
5075
|
if (targetNodeRid === this.nodeRid) {
|
|
@@ -4928,22 +5083,16 @@ export class ServiceStatefulRuntime {
|
|
|
4928
5083
|
);
|
|
4929
5084
|
return;
|
|
4930
5085
|
}
|
|
4931
|
-
void this.requestDurableOperation(
|
|
4932
|
-
targetNodeRid,
|
|
4933
|
-
parts,
|
|
4934
|
-
pending.id,
|
|
4935
|
-
'actorJoin',
|
|
4936
|
-
deadlineMs
|
|
4937
|
-
).then(
|
|
5086
|
+
void this.requestDurableOperation(targetNodeRid, parts, pending.id, 'actorJoin', pending).then(
|
|
4938
5087
|
(reply) => this.completeRemoteReply(pending, targetNodeRid, 'actorJoin', actor, reply),
|
|
4939
5088
|
(error) => {
|
|
4940
5089
|
this.canonicalActorJoinHandoffs.delete(pending.id);
|
|
4941
|
-
|
|
5090
|
+
pending.replyFailure(error);
|
|
4942
5091
|
}
|
|
4943
5092
|
);
|
|
4944
5093
|
}
|
|
4945
5094
|
|
|
4946
|
-
|
|
5095
|
+
async submitLocalRequest(
|
|
4947
5096
|
ingress: RawServiceIngressRecord,
|
|
4948
5097
|
pending: ServiceStatefulPendingOperation,
|
|
4949
5098
|
operationKind:
|
|
@@ -4956,7 +5105,8 @@ export class ServiceStatefulRuntime {
|
|
|
4956
5105
|
| 'streamUnbind'
|
|
4957
5106
|
| 'instanceSpotRequest',
|
|
4958
5107
|
actor?: ServiceActorRef,
|
|
4959
|
-
deadlineUnixMs?: bigint
|
|
5108
|
+
deadlineUnixMs?: bigint,
|
|
5109
|
+
receiver?: import('./operation-registry').OperationObserver<unknown, unknown>
|
|
4960
5110
|
): Promise<void> {
|
|
4961
5111
|
const canonicalActorJoin =
|
|
4962
5112
|
operationKind === 'actorJoin' ? decodeActorJoin28(ingress.parts) : undefined;
|
|
@@ -4969,15 +5119,14 @@ export class ServiceStatefulRuntime {
|
|
|
4969
5119
|
? ingress.parts.length < 2
|
|
4970
5120
|
? undefined
|
|
4971
5121
|
: ingress.parts[1]
|
|
4972
|
-
:
|
|
5122
|
+
: encodeOwnedApplicationPayload({
|
|
4973
5123
|
packetName: canonicalActorJoin.payload.packetName,
|
|
4974
5124
|
contentType: canonicalActorJoin.payload.contentType,
|
|
4975
5125
|
payload: Buffer.from(canonicalActorJoin.payload.payload)
|
|
4976
5126
|
});
|
|
4977
5127
|
if (decoded.kind === 'actorLookup') {
|
|
4978
5128
|
const found = this.registry.actor(decoded.actorId);
|
|
4979
|
-
|
|
4980
|
-
pending.id,
|
|
5129
|
+
pending.reply(
|
|
4981
5130
|
found === undefined
|
|
4982
5131
|
? { terminalResult: RequestResult.NotFound, failureCode: ACTOR_ROUTE_NOT_FOUND }
|
|
4983
5132
|
: {
|
|
@@ -4991,9 +5140,9 @@ export class ServiceStatefulRuntime {
|
|
|
4991
5140
|
if (decoded.kind === 'actorDestroy') {
|
|
4992
5141
|
try {
|
|
4993
5142
|
this.registry.destroyActor(decoded.actor.actor);
|
|
4994
|
-
|
|
5143
|
+
pending.reply({ terminalResult: RequestResult.Ok, failureCode: 0 });
|
|
4995
5144
|
} catch (error) {
|
|
4996
|
-
|
|
5145
|
+
pending.reply(failure(error));
|
|
4997
5146
|
}
|
|
4998
5147
|
return;
|
|
4999
5148
|
}
|
|
@@ -5002,11 +5151,19 @@ export class ServiceStatefulRuntime {
|
|
|
5002
5151
|
failureCode,
|
|
5003
5152
|
replyPayload,
|
|
5004
5153
|
tail
|
|
5005
|
-
) =>
|
|
5006
|
-
this.
|
|
5007
|
-
|
|
5008
|
-
|
|
5154
|
+
) => {
|
|
5155
|
+
const result = this.resultFromReply(
|
|
5156
|
+
terminalResult,
|
|
5157
|
+
failureCode,
|
|
5158
|
+
replyPayload,
|
|
5159
|
+
tail,
|
|
5160
|
+
this.nodeRid,
|
|
5161
|
+
actor
|
|
5009
5162
|
);
|
|
5163
|
+
if (receiver === undefined) return pending.reply(result);
|
|
5164
|
+
receiver.operationCompleted(pending.id, result, undefined);
|
|
5165
|
+
return true;
|
|
5166
|
+
};
|
|
5010
5167
|
if (decoded.kind === 'spotRequest') {
|
|
5011
5168
|
this.validateDirectSpotFence(decoded.target);
|
|
5012
5169
|
this.enqueueApplicationFrame(ingress, `spot:${decoded.target.spot.spotId}`, payloadFrame!, {
|
|
@@ -5075,7 +5232,7 @@ export class ServiceStatefulRuntime {
|
|
|
5075
5232
|
this.enqueueLifecycleFrame(
|
|
5076
5233
|
ingress,
|
|
5077
5234
|
`spot:${decoded.target.spot.spotId}`,
|
|
5078
|
-
payloadFrame ??
|
|
5235
|
+
payloadFrame ?? encodeOwnedApplicationPayload(emptyPayload()),
|
|
5079
5236
|
{
|
|
5080
5237
|
receiveKind: ReceiveKind.SpotControl,
|
|
5081
5238
|
operationKind: OperationKind.ActorJoin,
|
|
@@ -5092,7 +5249,7 @@ export class ServiceStatefulRuntime {
|
|
|
5092
5249
|
payload: Buffer.from(canonicalActorJoin.payload.payload)
|
|
5093
5250
|
}
|
|
5094
5251
|
}),
|
|
5095
|
-
isPending: () =>
|
|
5252
|
+
isPending: () => pending.isPending(),
|
|
5096
5253
|
...(deadlineUnixMs === undefined ? {} : { deadlineUnixMs }),
|
|
5097
5254
|
onTerminalCompletion: () => completeOnJoinDispatchTerminal?.(),
|
|
5098
5255
|
reply: (terminalResult, failureCode, replyPayload, tail) => {
|
|
@@ -5101,7 +5258,7 @@ export class ServiceStatefulRuntime {
|
|
|
5101
5258
|
terminalResult === RequestResult.Ok &&
|
|
5102
5259
|
tail?.kind === 'actorJoin' &&
|
|
5103
5260
|
tail.joinResult === 0;
|
|
5104
|
-
if (acceptedJoin &&
|
|
5261
|
+
if (acceptedJoin && pending.isPending()) {
|
|
5105
5262
|
// Commit membership now, but keep the source operation behind
|
|
5106
5263
|
// target OnJoinedActor. Entry finishes on this record; User
|
|
5107
5264
|
// Spot lifecycle finishes on the Joined control below.
|
|
@@ -5158,9 +5315,9 @@ export class ServiceStatefulRuntime {
|
|
|
5158
5315
|
this.nodeRid
|
|
5159
5316
|
);
|
|
5160
5317
|
}
|
|
5161
|
-
|
|
5318
|
+
pending.reply({ terminalResult: RequestResult.Ok, failureCode: 0 });
|
|
5162
5319
|
} catch (error) {
|
|
5163
|
-
|
|
5320
|
+
pending.reply(failure(error));
|
|
5164
5321
|
}
|
|
5165
5322
|
return;
|
|
5166
5323
|
}
|
|
@@ -5178,7 +5335,7 @@ export class ServiceStatefulRuntime {
|
|
|
5178
5335
|
);
|
|
5179
5336
|
return;
|
|
5180
5337
|
}
|
|
5181
|
-
|
|
5338
|
+
pending.reply({
|
|
5182
5339
|
terminalResult: RequestResult.ProtocolError,
|
|
5183
5340
|
failureCode: 0
|
|
5184
5341
|
});
|
|
@@ -5186,7 +5343,7 @@ export class ServiceStatefulRuntime {
|
|
|
5186
5343
|
}
|
|
5187
5344
|
|
|
5188
5345
|
private completeRemoteReply(
|
|
5189
|
-
pending: Pick<ServiceStatefulPendingOperation, 'id'>,
|
|
5346
|
+
pending: Pick<ServiceStatefulPendingOperation, 'id' | 'reply' | 'replyFailure'>,
|
|
5190
5347
|
targetNodeRid: string,
|
|
5191
5348
|
operationKind:
|
|
5192
5349
|
| 'spotRequest'
|
|
@@ -5199,7 +5356,8 @@ export class ServiceStatefulRuntime {
|
|
|
5199
5356
|
| 'boundSessionClose'
|
|
5200
5357
|
| 'instanceSpotRequest',
|
|
5201
5358
|
actor: ServiceActorRef | undefined,
|
|
5202
|
-
reply: readonly Buffer[]
|
|
5359
|
+
reply: readonly Buffer[],
|
|
5360
|
+
receiver?: import('./operation-registry').OperationObserver<unknown, unknown>
|
|
5203
5361
|
): void {
|
|
5204
5362
|
const canonicalActorJoinHandoffId =
|
|
5205
5363
|
operationKind === 'actorJoin' ? this.canonicalActorJoinHandoffs.get(pending.id) : undefined;
|
|
@@ -5208,23 +5366,23 @@ export class ServiceStatefulRuntime {
|
|
|
5208
5366
|
throw new ServiceWireProtocolError('Invalid M6B reply parts.');
|
|
5209
5367
|
const decoded = decodeStatefulReply(reply[0]!, pending.id, operationKind, reply.length >= 2);
|
|
5210
5368
|
const payload = reply.length < 2 ? undefined : decodeApplicationPayload(reply[1]);
|
|
5211
|
-
this.
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
actor,
|
|
5220
|
-
canonicalActorJoinHandoffId
|
|
5221
|
-
)
|
|
5369
|
+
const result = this.resultFromReply(
|
|
5370
|
+
decoded.terminalResult,
|
|
5371
|
+
decoded.failureCode,
|
|
5372
|
+
payload,
|
|
5373
|
+
decoded.tail,
|
|
5374
|
+
targetNodeRid,
|
|
5375
|
+
actor,
|
|
5376
|
+
canonicalActorJoinHandoffId
|
|
5222
5377
|
);
|
|
5378
|
+
if (receiver === undefined) pending.reply(result);
|
|
5379
|
+
else receiver.operationCompleted(pending.id, result, undefined);
|
|
5223
5380
|
} catch (error) {
|
|
5224
5381
|
// Spec 32-framework-error-model:58-60, 91-92 — an unprocessable remote
|
|
5225
5382
|
// reply (decode/shape failure) fails the awaiting operation with a
|
|
5226
5383
|
// Framework ProtocolError instead of leaking the codec's plain Error.
|
|
5227
|
-
|
|
5384
|
+
if (receiver === undefined) pending.replyFailure(translateWireReplyDecodeError(error));
|
|
5385
|
+
else receiver.operationFailed(pending.id, translateWireReplyDecodeError(error), undefined);
|
|
5228
5386
|
} finally {
|
|
5229
5387
|
if (operationKind === 'actorJoin') {
|
|
5230
5388
|
this.canonicalActorJoinHandoffs.delete(pending.id);
|
|
@@ -5284,6 +5442,7 @@ export class ServiceStatefulRuntime {
|
|
|
5284
5442
|
return {
|
|
5285
5443
|
terminalResult,
|
|
5286
5444
|
failureCode,
|
|
5445
|
+
...(tail?.kind === 'streamBindRejected' ? { failureMessage: tail.rejectionMessage } : {}),
|
|
5287
5446
|
...(payload === undefined ? {} : { payload }),
|
|
5288
5447
|
...(tail?.kind === 'streamBind'
|
|
5289
5448
|
? {
|
|
@@ -5297,7 +5456,7 @@ export class ServiceStatefulRuntime {
|
|
|
5297
5456
|
};
|
|
5298
5457
|
}
|
|
5299
5458
|
|
|
5300
|
-
|
|
5459
|
+
validateActorFence(fence: ServiceActorRouteFence): ServiceActorState {
|
|
5301
5460
|
if (
|
|
5302
5461
|
fence.actor.nodeRid !== this.nodeRid ||
|
|
5303
5462
|
fence.targetNodeGeneration !== this.nodeGeneration
|
|
@@ -5311,7 +5470,7 @@ export class ServiceStatefulRuntime {
|
|
|
5311
5470
|
return actor;
|
|
5312
5471
|
}
|
|
5313
5472
|
|
|
5314
|
-
|
|
5473
|
+
validateActorMessageFence(fence: ServiceActorRouteFence): ServiceActorState {
|
|
5315
5474
|
if (
|
|
5316
5475
|
fence.actor.nodeRid !== this.nodeRid ||
|
|
5317
5476
|
fence.targetNodeGeneration !== this.nodeGeneration
|
|
@@ -5342,7 +5501,7 @@ export class ServiceStatefulRuntime {
|
|
|
5342
5501
|
return spot;
|
|
5343
5502
|
}
|
|
5344
5503
|
|
|
5345
|
-
|
|
5504
|
+
validateDirectSpotFence(fence: ServiceSpotRouteFence): ServiceSpotState {
|
|
5346
5505
|
if (
|
|
5347
5506
|
fence.targetNodeRid !== this.nodeRid ||
|
|
5348
5507
|
fence.targetNodeGeneration !== this.nodeGeneration
|
|
@@ -5476,11 +5635,15 @@ export class ServiceStatefulRuntime {
|
|
|
5476
5635
|
1,
|
|
5477
5636
|
Math.min(30_000, Math.ceil(state.expiresAtMs - performance.now()))
|
|
5478
5637
|
);
|
|
5479
|
-
const
|
|
5638
|
+
const pending = this.raw.beginInfrastructureRequest(remainingMs);
|
|
5639
|
+
const reply = await requestDurableService(
|
|
5640
|
+
this.raw,
|
|
5480
5641
|
state.target.targetNodeRid,
|
|
5481
5642
|
parts,
|
|
5482
|
-
|
|
5643
|
+
pending,
|
|
5644
|
+
'spot message follow'
|
|
5483
5645
|
);
|
|
5646
|
+
pending.complete(reply);
|
|
5484
5647
|
this.raw.replyService(current.ingress, reply);
|
|
5485
5648
|
} catch (error) {
|
|
5486
5649
|
const result = failure(error);
|
|
@@ -5670,9 +5833,7 @@ export class ServiceStatefulRuntime {
|
|
|
5670
5833
|
|
|
5671
5834
|
private tryEntrySpotFence(targetNodeRid: string): ServiceDirectSpotRouteFence | undefined {
|
|
5672
5835
|
const targetNodeGeneration =
|
|
5673
|
-
targetNodeRid
|
|
5674
|
-
? this.nodeGeneration
|
|
5675
|
-
: this.raw.topology.peer(targetNodeRid)?.descriptor.lifecycleGeneration;
|
|
5836
|
+
this.raw.peerLifecycleGeneration(targetNodeRid) ?? this.tryPeerGeneration(targetNodeRid);
|
|
5676
5837
|
if (targetNodeGeneration === undefined) return undefined;
|
|
5677
5838
|
return {
|
|
5678
5839
|
spot: {
|
|
@@ -5715,8 +5876,10 @@ export class ServiceStatefulRuntime {
|
|
|
5715
5876
|
? current
|
|
5716
5877
|
: undefined;
|
|
5717
5878
|
}
|
|
5718
|
-
|
|
5719
|
-
|
|
5879
|
+
if (
|
|
5880
|
+
(this.raw.peerLifecycleGeneration(targetNodeRid) ?? this.tryPeerGeneration(targetNodeRid)) !==
|
|
5881
|
+
targetNodeGeneration
|
|
5882
|
+
) {
|
|
5720
5883
|
return undefined;
|
|
5721
5884
|
}
|
|
5722
5885
|
this.rememberSpotRoute(requested);
|
|
@@ -6311,6 +6474,10 @@ function emptyPayload(): ServiceApplicationPayload {
|
|
|
6311
6474
|
};
|
|
6312
6475
|
}
|
|
6313
6476
|
|
|
6477
|
+
function copyRetainedServiceFrames(parts: readonly Buffer[]): Buffer[] {
|
|
6478
|
+
return parts.map((part) => copyPayloadBytes(part));
|
|
6479
|
+
}
|
|
6480
|
+
|
|
6314
6481
|
/**
|
|
6315
6482
|
* The generated command-28 decoder is the canonical wire authority. Keep
|
|
6316
6483
|
* the stateful mailbox's internal record shape as an adapter only; it must
|