@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,9 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RawServiceMeshRuntime = exports.RAW_MESH_RECEIVE_TIME_BUDGET_MS = void 0;
|
|
4
|
+
const framework_errors_internal_1 = require("../framework-errors-internal");
|
|
5
|
+
const durable_service_request_1 = require("./durable-service-request");
|
|
6
|
+
const request_deadline_1 = require("../messaging/request-deadline");
|
|
7
|
+
const internal_observation_1 = require("../internal-observation");
|
|
4
8
|
const node_os_1 = require("node:os");
|
|
5
9
|
const application_ingress_record_owner_1 = require("../application-jobs/application-ingress-record-owner");
|
|
6
10
|
const submission_result_1 = require("../messaging/submission-result");
|
|
11
|
+
const payload_slab_1 = require("../../contracts/Common/payload-slab");
|
|
7
12
|
const runtime_values_1 = require("../backend/runtime-values");
|
|
8
13
|
const service_wire_codec_generated_1 = require("../protocol/service_wire_codec.generated");
|
|
9
14
|
const service_wire_binary_primitives_1 = require("./service-wire-binary-primitives");
|
|
@@ -32,9 +37,20 @@ const livenessCodec = (0, service_wire_codec_1.createServiceWireCodec)({
|
|
|
32
37
|
* It owns protocol, admission, mailbox, request and liveness state.
|
|
33
38
|
*/
|
|
34
39
|
class RawServiceMeshRuntime {
|
|
40
|
+
[internal_observation_1.inspectRuntime](nodeRoutingId) {
|
|
41
|
+
return Object.freeze({
|
|
42
|
+
pendingControlSends: this.controlSends.size,
|
|
43
|
+
selectedRouteGeneration: nodeRoutingId === undefined ? undefined : this.selectedRoutes.get(nodeRoutingId),
|
|
44
|
+
peerRouteObservers: this.peerRouteChanged.size,
|
|
45
|
+
peerConnectionIntentObservers: this.peerConnectionIntentRemoved.size,
|
|
46
|
+
expectedPeers: this.expectedPeers.size
|
|
47
|
+
});
|
|
48
|
+
}
|
|
35
49
|
topology;
|
|
36
50
|
mailbox;
|
|
37
51
|
liveness;
|
|
52
|
+
requestOwner;
|
|
53
|
+
releaseOperations;
|
|
38
54
|
operations;
|
|
39
55
|
expectedPeers = new Map();
|
|
40
56
|
endpointOnlyPeers = new Set();
|
|
@@ -45,6 +61,7 @@ class RawServiceMeshRuntime {
|
|
|
45
61
|
* RID -> route generation. Only `observeSelectedRoutes` replaces it.
|
|
46
62
|
*/
|
|
47
63
|
selectedRoutes = new Map();
|
|
64
|
+
connectionAttempts = [];
|
|
48
65
|
bindingPort;
|
|
49
66
|
applicationJobQueue;
|
|
50
67
|
nodeMailboxOwner;
|
|
@@ -70,9 +87,16 @@ class RawServiceMeshRuntime {
|
|
|
70
87
|
serviceIngressAccepts;
|
|
71
88
|
closed = false;
|
|
72
89
|
constructor(options) {
|
|
90
|
+
this.requestOwner = options.requests;
|
|
73
91
|
this.onReceiveReady = options.onReceiveReady;
|
|
74
92
|
this.infrastructureTaskRunner = options.infrastructureTaskRunner;
|
|
75
|
-
this.operations =
|
|
93
|
+
this.operations =
|
|
94
|
+
options.requests?.operations() ??
|
|
95
|
+
new operation_registry_1.OperationRegistry(undefined, options.onPendingOperationsChanged, (reason) => (0, request_deadline_1.requestTerminalError)('Request', reason));
|
|
96
|
+
this.releaseOperations =
|
|
97
|
+
options.requests === undefined
|
|
98
|
+
? () => this.operations.close('Raw service runtime closed.')
|
|
99
|
+
: () => { };
|
|
76
100
|
this.descriptor = options.descriptor;
|
|
77
101
|
this.nodeMailboxOwner = `node:${options.descriptor.nodeRoutingId}`;
|
|
78
102
|
this.topology = new service_topology_registry_1.ServiceTopologyRegistry(options.descriptor);
|
|
@@ -132,6 +156,7 @@ class RawServiceMeshRuntime {
|
|
|
132
156
|
securityIdentity: expected.securityIdentity,
|
|
133
157
|
lifecycleGeneration: expected.lifecycleGeneration
|
|
134
158
|
}));
|
|
159
|
+
this.notifyPeerRouteChanged(expected.nodeRoutingId);
|
|
135
160
|
}
|
|
136
161
|
connectPeerByRoutingId(endpoint, nodeRoutingId, securityIdentity, lifecycleGeneration) {
|
|
137
162
|
this.requireStarted().connectToRoutingId(nodeRoutingId, endpoint);
|
|
@@ -142,6 +167,7 @@ class RawServiceMeshRuntime {
|
|
|
142
167
|
securityIdentity,
|
|
143
168
|
lifecycleGeneration
|
|
144
169
|
}));
|
|
170
|
+
this.notifyPeerRouteChanged(nodeRoutingId);
|
|
145
171
|
}
|
|
146
172
|
expectPeerByRoutingId(endpoint, nodeRoutingId, securityIdentity, lifecycleGeneration) {
|
|
147
173
|
this.expectedPeers.set(nodeRoutingId, Object.assign(this.expectedPeers.get(nodeRoutingId) ?? {}, {
|
|
@@ -151,6 +177,7 @@ class RawServiceMeshRuntime {
|
|
|
151
177
|
securityIdentity,
|
|
152
178
|
lifecycleGeneration
|
|
153
179
|
}));
|
|
180
|
+
this.notifyPeerRouteChanged(nodeRoutingId);
|
|
154
181
|
}
|
|
155
182
|
connectPeerEndpoint(endpoint) {
|
|
156
183
|
this.requireStarted().connect(endpoint);
|
|
@@ -233,12 +260,23 @@ class RawServiceMeshRuntime {
|
|
|
233
260
|
}
|
|
234
261
|
observePeerRoute(nodeRoutingId) {
|
|
235
262
|
const selected = this.selectedRoutes.get(nodeRoutingId);
|
|
236
|
-
const
|
|
263
|
+
const peer = this.topology.admittedPeer(nodeRoutingId);
|
|
264
|
+
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
265
|
+
const admitted = peer?.liveness?.connectionId;
|
|
237
266
|
return {
|
|
238
267
|
generation: selected ?? (typeof admitted === 'bigint' ? admitted : undefined),
|
|
239
|
-
ready:
|
|
268
|
+
ready: peer?.remoteAdmitReceived === true,
|
|
269
|
+
selected: selected !== undefined,
|
|
270
|
+
lifecycleGeneration: expected?.lifecycleGeneration ?? peer?.descriptor.lifecycleGeneration,
|
|
271
|
+
endpoint: expected?.endpoint ?? peer?.descriptor.advertisedEndpoint,
|
|
272
|
+
// The immutable socket snapshot is borrowed; only waiting admission filters it.
|
|
273
|
+
connectionAttempts: this.connectionAttempts
|
|
240
274
|
};
|
|
241
275
|
}
|
|
276
|
+
peerLifecycleGeneration(nodeRoutingId) {
|
|
277
|
+
return (this.expectedPeers.get(nodeRoutingId)?.lifecycleGeneration ??
|
|
278
|
+
this.topology.admittedPeer(nodeRoutingId)?.descriptor.lifecycleGeneration);
|
|
279
|
+
}
|
|
242
280
|
async waitForPeerRoute(nodeRoutingId, lifecycleGeneration, deadlineUnixMs, signal) {
|
|
243
281
|
const remaining = deadlineUnixMs - BigInt(Date.now());
|
|
244
282
|
if (remaining <= 0n)
|
|
@@ -246,14 +284,14 @@ class RawServiceMeshRuntime {
|
|
|
246
284
|
const pending = this.operations.register(Number(remaining));
|
|
247
285
|
const check = () => {
|
|
248
286
|
if (this.isPeerRouteReady(nodeRoutingId, lifecycleGeneration)) {
|
|
249
|
-
|
|
287
|
+
pending.reply({ terminalResult: runtime_values_1.RequestResult.Ok, failureCode: 0 });
|
|
250
288
|
}
|
|
251
289
|
};
|
|
252
290
|
const unsubscribe = this.observePeerRouteChanged((rid) => {
|
|
253
291
|
if (rid === nodeRoutingId)
|
|
254
292
|
check();
|
|
255
293
|
});
|
|
256
|
-
const abort = () =>
|
|
294
|
+
const abort = () => pending.replyFailure(signal?.reason);
|
|
257
295
|
signal?.addEventListener('abort', abort, { once: true });
|
|
258
296
|
try {
|
|
259
297
|
if (signal?.aborted === true)
|
|
@@ -299,27 +337,28 @@ class RawServiceMeshRuntime {
|
|
|
299
337
|
return false;
|
|
300
338
|
const key = controlSendKey(nodeRoutingId, service_wire_m6a_codec_1.M6aServiceWireCommand.hello);
|
|
301
339
|
if (!this.isPeerAnnouncementCurrent(nodeRoutingId, generation)) {
|
|
302
|
-
this.controlSends.delete(key);
|
|
303
340
|
return false;
|
|
304
341
|
}
|
|
305
|
-
const current = () => this.isPeerAnnouncementCurrent(nodeRoutingId, generation)
|
|
342
|
+
const current = () => this.isPeerAnnouncementCurrent(nodeRoutingId, generation) &&
|
|
343
|
+
this.peerAdmissionSealed?.() !== true;
|
|
306
344
|
const existing = this.controlSends.get(key);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
345
|
+
if (!current()) {
|
|
346
|
+
if (existing === undefined)
|
|
347
|
+
this.controlSends.set(key, { current });
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
const hello = existing?.hello ??
|
|
351
|
+
(0, service_wire_m6a_codec_1.encodeRouteMeshAdmission)(service_wire_m6a_codec_1.M6aServiceWireCommand.hello, this.topology.localDescriptor());
|
|
310
352
|
return this.startControlSend(nodeRoutingId, service_wire_m6a_codec_1.M6aServiceWireCommand.hello, () => this.submitControl(nodeRoutingId, [hello]), current, hello);
|
|
311
353
|
}
|
|
312
354
|
isPeerAnnouncementCurrent(nodeRoutingId, generation) {
|
|
313
|
-
const admission = this.topology.routeAdmission(nodeRoutingId);
|
|
314
355
|
return (this.selectedRoutes.get(nodeRoutingId) === generation &&
|
|
315
|
-
!(
|
|
316
|
-
admission.remoteAdmitReceived === true) &&
|
|
317
|
-
this.peerAdmissionSealed?.() !== true);
|
|
356
|
+
!this.topology.hasRemoteAdmit(nodeRoutingId, routeConnectionId(generation)));
|
|
318
357
|
}
|
|
319
358
|
isPeerRouteReady(nodeRoutingId, lifecycleGeneration) {
|
|
320
359
|
// Admission is bound to the observed selected route: the route observer
|
|
321
360
|
// removes the peer when that route ends or is replaced.
|
|
322
|
-
const peer = this.topology.
|
|
361
|
+
const peer = this.topology.readyPeer(nodeRoutingId);
|
|
323
362
|
return (peer !== undefined &&
|
|
324
363
|
(lifecycleGeneration === undefined ||
|
|
325
364
|
peer.descriptor.lifecycleGeneration === lifecycleGeneration));
|
|
@@ -373,58 +412,78 @@ class RawServiceMeshRuntime {
|
|
|
373
412
|
sendToNode(targetNodeRoutingId, payload) {
|
|
374
413
|
return this.send(targetNodeRoutingId, [NODE_SEND_HEADER, this.applicationFrame(payload)]);
|
|
375
414
|
}
|
|
376
|
-
|
|
415
|
+
sendToChannel(channelName, payload) {
|
|
377
416
|
const selection = this.selectChannelTarget(channelName);
|
|
378
417
|
if (selection.kind !== 'selected')
|
|
379
418
|
return selection.submitResult;
|
|
380
419
|
const selected = selection.peer;
|
|
381
420
|
const applicationFrame = this.applicationFrame(payload);
|
|
382
|
-
|
|
421
|
+
const submitted = this.send(selected.descriptor.nodeRoutingId, [
|
|
383
422
|
(0, service_wire_m6a_codec_1.encodeChannelSendHeader)(channelName),
|
|
384
423
|
applicationFrame
|
|
385
|
-
])
|
|
386
|
-
|
|
387
|
-
|
|
424
|
+
]);
|
|
425
|
+
return typeof submitted === 'boolean'
|
|
426
|
+
? channelSendSubmitResult(submitted)
|
|
427
|
+
: submitted.then(channelSendSubmitResult);
|
|
388
428
|
}
|
|
389
|
-
requestToNode(targetNodeRoutingId, payload, timeoutMs, onAdmitted, observer, operationKind) {
|
|
390
|
-
return this.requestToTarget(targetNodeRoutingId, payload, timeoutMs, undefined, onAdmitted, observer, operationKind);
|
|
429
|
+
requestToNode(targetNodeRoutingId, payload, timeoutMs, onAdmitted, observer, operationKind, requestOperation) {
|
|
430
|
+
return this.requestToTarget(targetNodeRoutingId, payload, timeoutMs, undefined, onAdmitted, observer, operationKind, requestOperation);
|
|
391
431
|
}
|
|
392
|
-
requestToChannel(channelName, payload, timeoutMs, onAdmitted, observer, operationKind) {
|
|
432
|
+
requestToChannel(channelName, payload, timeoutMs, onAdmitted, observer, operationKind, requestOperation) {
|
|
393
433
|
const selection = this.selectChannelTarget(channelName);
|
|
394
434
|
if (selection.kind !== 'selected') {
|
|
395
|
-
const pending = this.registerRequest(timeoutMs, observer, operationKind);
|
|
396
|
-
this.completeRequest(pending, selection.requestResult);
|
|
435
|
+
const pending = this.registerRequest(timeoutMs, observer, operationKind, requestOperation);
|
|
436
|
+
this.completeRequest(pending, selection.requestResult, requestOperation === undefined ? undefined : observer, operationKind);
|
|
397
437
|
return pending;
|
|
398
438
|
}
|
|
399
439
|
return this.requestToTarget(selection.peer.descriptor.nodeRoutingId, payload, timeoutMs, channelName, onAdmitted, observer, operationKind);
|
|
400
440
|
}
|
|
441
|
+
beginInfrastructureRequest(timeoutMs, signal, absoluteDeadlineMs = performance.now() + timeoutMs) {
|
|
442
|
+
const pending = this.operations.register(timeoutMs, 'registry', undefined, absoluteDeadlineMs);
|
|
443
|
+
pending.setSignal(signal);
|
|
444
|
+
return pending;
|
|
445
|
+
}
|
|
401
446
|
/**
|
|
402
447
|
* One pending entry per request: an observed request reports its terminal
|
|
403
448
|
* to the caller's observer; any other request keeps the Promise contract.
|
|
404
449
|
*/
|
|
405
|
-
registerRequest(timeoutMs, observer, operationKind) {
|
|
450
|
+
registerRequest(timeoutMs, observer, operationKind, requestOperation) {
|
|
451
|
+
if (requestOperation !== undefined) {
|
|
452
|
+
return requestOperation;
|
|
453
|
+
}
|
|
406
454
|
return observer === undefined
|
|
407
455
|
? this.operations.register(timeoutMs)
|
|
408
|
-
:
|
|
456
|
+
: this.observedRequest(this.operations.registerObserved(timeoutMs, observer, operationKind));
|
|
457
|
+
}
|
|
458
|
+
observedRequest(id) {
|
|
459
|
+
return this.operations.handle(id);
|
|
409
460
|
}
|
|
410
461
|
/**
|
|
411
462
|
* An observed caller learns the operation id only when the request call
|
|
412
463
|
* returns, so a terminal decided inside that call is delivered after it.
|
|
413
464
|
*/
|
|
414
|
-
completeRequest(pending, result) {
|
|
415
|
-
if (
|
|
416
|
-
queueMicrotask(() =>
|
|
465
|
+
completeRequest(pending, result, observer, operationKind) {
|
|
466
|
+
if (observer !== undefined) {
|
|
467
|
+
queueMicrotask(() => observer.operationCompleted(pending.id, result, operationKind));
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
if (pending.promise === undefined || pending.hasObserver())
|
|
471
|
+
queueMicrotask(() => pending.reply(result));
|
|
417
472
|
else
|
|
418
|
-
|
|
473
|
+
pending.reply(result);
|
|
419
474
|
}
|
|
420
|
-
failRequest(pending, error) {
|
|
475
|
+
failRequest(pending, error, observer, operationKind) {
|
|
476
|
+
if (observer !== undefined) {
|
|
477
|
+
queueMicrotask(() => observer.operationFailed(pending.id, error, operationKind));
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
421
480
|
if (pending.promise === undefined)
|
|
422
|
-
queueMicrotask(() =>
|
|
481
|
+
queueMicrotask(() => pending.replyFailure(error));
|
|
423
482
|
else
|
|
424
|
-
|
|
483
|
+
pending.replyFailure(error);
|
|
425
484
|
}
|
|
426
485
|
selectChannelTarget(channelName) {
|
|
427
|
-
const selected = this.topology.selectChannel(channelName
|
|
486
|
+
const selected = this.topology.selectChannel(channelName);
|
|
428
487
|
if (selected !== undefined)
|
|
429
488
|
return { kind: 'selected', peer: selected };
|
|
430
489
|
return this.topology.hasKnownChannelTarget(channelName)
|
|
@@ -465,9 +524,27 @@ class RawServiceMeshRuntime {
|
|
|
465
524
|
return this.sendFailure(error);
|
|
466
525
|
}
|
|
467
526
|
}
|
|
468
|
-
requestService(targetNodeRoutingId, parts, timeoutMs, onAdmitted) {
|
|
527
|
+
requestService(targetNodeRoutingId, parts, timeoutMs, onAdmitted, existing, receiver, onSubmitted) {
|
|
528
|
+
if (receiver !== undefined) {
|
|
529
|
+
try {
|
|
530
|
+
this.requireStarted().request(targetNodeRoutingId, parts, timeoutMs, (reply) => receiver.operationCompleted(existing?.id ?? 0n, reply, undefined), (error) => receiver.operationFailed(existing?.id ?? 0n, error, undefined), this.topology.admittedPeer(targetNodeRoutingId)?.liveness?.recordReceived, onAdmitted, existing);
|
|
531
|
+
}
|
|
532
|
+
catch (error) {
|
|
533
|
+
receiver.operationFailed(existing?.id ?? 0n, error, undefined);
|
|
534
|
+
}
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
469
537
|
const admission = this.topology.admittedPeer(targetNodeRoutingId)?.liveness;
|
|
470
|
-
|
|
538
|
+
try {
|
|
539
|
+
const reply = this.requireStarted().request(targetNodeRoutingId, parts, timeoutMs, (reply) => reply, (error) => {
|
|
540
|
+
throw error;
|
|
541
|
+
}, admission?.recordReceived, onAdmitted, existing);
|
|
542
|
+
onSubmitted?.();
|
|
543
|
+
return reply;
|
|
544
|
+
}
|
|
545
|
+
catch (error) {
|
|
546
|
+
return Promise.reject(error);
|
|
547
|
+
}
|
|
471
548
|
}
|
|
472
549
|
replyService(record, parts) {
|
|
473
550
|
if (record.requestSequence === undefined) {
|
|
@@ -486,10 +563,8 @@ class RawServiceMeshRuntime {
|
|
|
486
563
|
if (request.reply === undefined || request.correlation === undefined) {
|
|
487
564
|
throw new TypeError('Reply requires a request mailbox record.');
|
|
488
565
|
}
|
|
489
|
-
request.
|
|
490
|
-
|
|
491
|
-
...(terminalResult === 0 ? [this.applicationFrame(payload)] : [])
|
|
492
|
-
]);
|
|
566
|
+
const header = (0, service_wire_m6a_codec_1.encodeReplyHeader)(request.correlation, terminalResult, failureCode);
|
|
567
|
+
request.reply(terminalResult === 0 ? [header, this.applicationFrame(payload)] : [header]);
|
|
493
568
|
}
|
|
494
569
|
async pumpOne(nowMs = performance.now(), observe) {
|
|
495
570
|
const result = await this.receiveOne(nowMs, observe);
|
|
@@ -514,10 +589,35 @@ class RawServiceMeshRuntime {
|
|
|
514
589
|
this.requireStarted().setReadableHandler(handler);
|
|
515
590
|
}
|
|
516
591
|
/** Returns whether a receive budget ended before no-data; idle ticks only maintain peers. */
|
|
517
|
-
|
|
518
|
-
|
|
592
|
+
pumpBatch(receiveReady = true, routeReady = false, connectReady = false) {
|
|
593
|
+
try {
|
|
594
|
+
this.observeInfrastructureFailure();
|
|
595
|
+
if (routeReady || connectReady) {
|
|
596
|
+
return this.receiveBatchAfterObservations(receiveReady, routeReady, connectReady);
|
|
597
|
+
}
|
|
598
|
+
return this.receiveBatch(receiveReady);
|
|
599
|
+
}
|
|
600
|
+
catch (error) {
|
|
601
|
+
return Promise.reject(error);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
async receiveBatchAfterObservations(receiveReady, routeReady, connectReady) {
|
|
605
|
+
// Both facts are applied before admission observers run in this socket turn.
|
|
606
|
+
if (connectReady)
|
|
607
|
+
this.connectionAttempts = this.requireStarted().connectionAttemptsSnapshot();
|
|
519
608
|
if (routeReady)
|
|
520
609
|
await this.observeSelectedRoutes();
|
|
610
|
+
if (connectReady) {
|
|
611
|
+
for (const target of this.expectedPeers.keys())
|
|
612
|
+
this.notifyPeerRouteChanged(target);
|
|
613
|
+
for (const peer of this.topology.peers()) {
|
|
614
|
+
if (!this.expectedPeers.has(peer.descriptor.nodeRoutingId))
|
|
615
|
+
this.notifyPeerRouteChanged(peer.descriptor.nodeRoutingId);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
return this.receiveBatch(receiveReady);
|
|
619
|
+
}
|
|
620
|
+
receiveBatch(receiveReady) {
|
|
521
621
|
const startedAtMs = performance.now();
|
|
522
622
|
let messages = 0;
|
|
523
623
|
let bytes = 0;
|
|
@@ -527,29 +627,46 @@ class RawServiceMeshRuntime {
|
|
|
527
627
|
const rotation = (this.receiveRotation ??= this.applicationJobQueue.createReceiveRotation(RAW_MESH_RECEIVE_RECORD_BUDGET, 'remote'));
|
|
528
628
|
if (receiveReady)
|
|
529
629
|
rotation.reserve();
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
receiveReady
|
|
536
|
-
|
|
630
|
+
// The same loop owns both immediate receives and a suspended receive's
|
|
631
|
+
// continuation; only the latter needs a Promise and retains this frame.
|
|
632
|
+
const drain = (received) => {
|
|
633
|
+
try {
|
|
634
|
+
while (received !== undefined ||
|
|
635
|
+
(receiveReady && messages < RAW_MESH_RECEIVE_RECORD_BUDGET && !this.closed)) {
|
|
636
|
+
if (received === undefined) {
|
|
637
|
+
const pending = this.receiveOne(performance.now(), observe, rotation);
|
|
638
|
+
if (pending instanceof Promise) {
|
|
639
|
+
return pending.then(drain, (error) => {
|
|
640
|
+
rotation.releaseUnused();
|
|
641
|
+
throw error;
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
received = pending;
|
|
645
|
+
}
|
|
646
|
+
if (received === 'noData') {
|
|
647
|
+
receiveReady = false;
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
messages += 1;
|
|
651
|
+
received = undefined;
|
|
652
|
+
// Core owns the per-peer fair-queue cursor. The Framework limit bounds
|
|
653
|
+
// the entire round, so changing peers does not renew its byte/count budget.
|
|
654
|
+
if (bytes >= RAW_MESH_RECEIVE_BYTE_BUDGET ||
|
|
655
|
+
performance.now() - startedAtMs >= exports.RAW_MESH_RECEIVE_TIME_BUDGET_MS)
|
|
656
|
+
break;
|
|
537
657
|
}
|
|
538
|
-
messages += 1;
|
|
539
|
-
// Core owns the per-peer fair-queue cursor. The Framework limit bounds
|
|
540
|
-
// the entire round, so changing peers does not renew its byte/count budget.
|
|
541
|
-
if (bytes >= RAW_MESH_RECEIVE_BYTE_BUDGET ||
|
|
542
|
-
performance.now() - startedAtMs >= exports.RAW_MESH_RECEIVE_TIME_BUDGET_MS)
|
|
543
|
-
break;
|
|
544
658
|
}
|
|
545
|
-
|
|
546
|
-
|
|
659
|
+
catch (error) {
|
|
660
|
+
rotation.releaseUnused();
|
|
661
|
+
throw error;
|
|
662
|
+
}
|
|
547
663
|
rotation.releaseUnused();
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
664
|
+
if (!this.closed) {
|
|
665
|
+
this.tickLiveness();
|
|
666
|
+
}
|
|
667
|
+
return receiveReady && messages > 0;
|
|
668
|
+
};
|
|
669
|
+
return drain();
|
|
553
670
|
}
|
|
554
671
|
receiveOne(nowMs, observe, rotation) {
|
|
555
672
|
const router = this.requireStarted();
|
|
@@ -558,32 +675,7 @@ class RawServiceMeshRuntime {
|
|
|
558
675
|
this.receivePermit = undefined;
|
|
559
676
|
permit ??= rotation?.take();
|
|
560
677
|
if (permit === undefined && this.receiveAcquisition === undefined) {
|
|
561
|
-
|
|
562
|
-
let rejectAcquisition;
|
|
563
|
-
permit = this.applicationJobQueue.acquireOrResume((permit) => {
|
|
564
|
-
this.receiveAcquisition = undefined;
|
|
565
|
-
if (this.closed) {
|
|
566
|
-
permit.releaseAfterInternalProcessing();
|
|
567
|
-
permit.releaseStorage?.();
|
|
568
|
-
}
|
|
569
|
-
else {
|
|
570
|
-
this.receivePermit = permit;
|
|
571
|
-
this.onReceiveReady?.();
|
|
572
|
-
}
|
|
573
|
-
resolveAcquisition?.(permit);
|
|
574
|
-
}, (error) => rejectAcquisition?.(error), this.applicationJobStop.signal, 'remote');
|
|
575
|
-
if (permit === undefined) {
|
|
576
|
-
const acquisition = new Promise((resolve, reject) => {
|
|
577
|
-
resolveAcquisition = resolve;
|
|
578
|
-
rejectAcquisition = reject;
|
|
579
|
-
});
|
|
580
|
-
this.receiveAcquisition = acquisition;
|
|
581
|
-
acquisition.catch((error) => {
|
|
582
|
-
this.receiveAcquisition = undefined;
|
|
583
|
-
if (!this.applicationJobStop.signal.aborted)
|
|
584
|
-
this.reportInfrastructureFailure(error);
|
|
585
|
-
});
|
|
586
|
-
}
|
|
678
|
+
permit = this.acquireReceivePermit();
|
|
587
679
|
}
|
|
588
680
|
if (permit === undefined)
|
|
589
681
|
return 'noData';
|
|
@@ -616,20 +708,52 @@ class RawServiceMeshRuntime {
|
|
|
616
708
|
throw error;
|
|
617
709
|
}
|
|
618
710
|
return result instanceof Promise
|
|
619
|
-
?
|
|
620
|
-
applicationJobOwner.close();
|
|
621
|
-
throw error;
|
|
622
|
-
})
|
|
711
|
+
? this.finishPendingReceive(result, received, applicationJobOwner, observe)
|
|
623
712
|
: this.finishReceive(received, applicationJobOwner, observe, result);
|
|
624
713
|
}
|
|
714
|
+
acquireReceivePermit() {
|
|
715
|
+
let resolveAcquisition;
|
|
716
|
+
let rejectAcquisition;
|
|
717
|
+
const permit = this.applicationJobQueue.acquireOrResume((permit) => {
|
|
718
|
+
this.receiveAcquisition = undefined;
|
|
719
|
+
if (this.closed) {
|
|
720
|
+
permit.releaseAfterInternalProcessing();
|
|
721
|
+
permit.releaseStorage?.();
|
|
722
|
+
}
|
|
723
|
+
else {
|
|
724
|
+
this.receivePermit = permit;
|
|
725
|
+
this.onReceiveReady?.();
|
|
726
|
+
}
|
|
727
|
+
resolveAcquisition?.(permit);
|
|
728
|
+
}, (error) => rejectAcquisition?.(error), this.applicationJobStop.signal, 'remote');
|
|
729
|
+
if (permit === undefined) {
|
|
730
|
+
const acquisition = new Promise((resolve, reject) => {
|
|
731
|
+
resolveAcquisition = resolve;
|
|
732
|
+
rejectAcquisition = reject;
|
|
733
|
+
});
|
|
734
|
+
this.receiveAcquisition = acquisition;
|
|
735
|
+
acquisition.catch((error) => {
|
|
736
|
+
this.receiveAcquisition = undefined;
|
|
737
|
+
if (!this.applicationJobStop.signal.aborted)
|
|
738
|
+
this.reportInfrastructureFailure(error);
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
return permit;
|
|
742
|
+
}
|
|
743
|
+
finishPendingReceive(result, received, owner, observe) {
|
|
744
|
+
return result.then((value) => this.finishReceive(received, owner, observe, value), (error) => {
|
|
745
|
+
owner.close();
|
|
746
|
+
throw error;
|
|
747
|
+
});
|
|
748
|
+
}
|
|
625
749
|
finishReceive(received, owner, observe, result) {
|
|
626
750
|
try {
|
|
627
751
|
if (result === 'protocolError')
|
|
628
752
|
this.reportProtocolError(received);
|
|
629
753
|
if (observe !== undefined) {
|
|
630
754
|
let bytes = 0;
|
|
631
|
-
for (
|
|
632
|
-
bytes +=
|
|
755
|
+
for (let index = 0; index < received.parts.length; index += 1)
|
|
756
|
+
bytes += received.parts[index].byteLength;
|
|
633
757
|
observe(received.sourceRid, bytes);
|
|
634
758
|
}
|
|
635
759
|
return result;
|
|
@@ -651,28 +775,13 @@ class RawServiceMeshRuntime {
|
|
|
651
775
|
replyGenericProtocolError(received) {
|
|
652
776
|
if (received.requestSeq === undefined || received.parts.length === 0)
|
|
653
777
|
return false;
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
if (correlation === undefined)
|
|
662
|
-
return false;
|
|
663
|
-
const reply = [
|
|
664
|
-
(0, service_wire_m6a_codec_1.encodeReplyHeader)(correlation, runtime_values_1.RequestResult.ProtocolError, service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.requestProtocolError)
|
|
665
|
-
];
|
|
666
|
-
if (received.reply === undefined)
|
|
667
|
-
return false;
|
|
668
|
-
received.reply(reply);
|
|
669
|
-
return true;
|
|
670
|
-
}
|
|
671
|
-
catch (error) {
|
|
672
|
-
if (error instanceof service_wire_m6a_codec_1.ServiceWireProtocolError)
|
|
673
|
-
return false;
|
|
674
|
-
throw error;
|
|
675
|
-
}
|
|
778
|
+
const correlation = (0, service_wire_constants_generated_1.recoverRequestCorrelation)(received.parts[0]);
|
|
779
|
+
if (correlation === undefined || received.reply === undefined)
|
|
780
|
+
return false;
|
|
781
|
+
received.reply([
|
|
782
|
+
(0, service_wire_m6a_codec_1.encodeReplyHeader)(correlation, runtime_values_1.RequestResult.ProtocolError, service_wire_constants_generated_1.ServiceWireFrameworkErrorCode.requestProtocolError)
|
|
783
|
+
]);
|
|
784
|
+
return true;
|
|
676
785
|
}
|
|
677
786
|
processReceived(received, nowMs, applicationJobOwner) {
|
|
678
787
|
const peer = this.topology.admittedPeer(received.sourceRid);
|
|
@@ -686,7 +795,7 @@ class RawServiceMeshRuntime {
|
|
|
686
795
|
}
|
|
687
796
|
if (header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.hello ||
|
|
688
797
|
header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.admit) {
|
|
689
|
-
return this.processAdmission(received, header, nowMs)
|
|
798
|
+
return this.finishPendingProtocolReceive(this.processAdmission(received, header, nowMs));
|
|
690
799
|
}
|
|
691
800
|
if (header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.reject) {
|
|
692
801
|
if (received.parts.length !== 1)
|
|
@@ -698,11 +807,11 @@ class RawServiceMeshRuntime {
|
|
|
698
807
|
return 'dropped';
|
|
699
808
|
this.liveness.recordReceived(peer.liveness, nowMs);
|
|
700
809
|
if (header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.update) {
|
|
701
|
-
return this.processAdmission(received, header, nowMs)
|
|
810
|
+
return this.finishPendingProtocolReceive(this.processAdmission(received, header, nowMs));
|
|
702
811
|
}
|
|
703
812
|
if (header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.livenessProbe ||
|
|
704
813
|
header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.livenessAck) {
|
|
705
|
-
return this.processLiveness(received, nowMs)
|
|
814
|
+
return this.finishPendingProtocolReceive(this.processLiveness(received, nowMs));
|
|
706
815
|
}
|
|
707
816
|
const stateful = this.serviceIngress !== undefined && this.serviceIngressAccepts?.(header.command) !== false
|
|
708
817
|
? this.serviceIngress({
|
|
@@ -720,7 +829,7 @@ class RawServiceMeshRuntime {
|
|
|
720
829
|
})
|
|
721
830
|
: undefined;
|
|
722
831
|
if (stateful instanceof Promise)
|
|
723
|
-
return
|
|
832
|
+
return this.finishPendingStatefulReceive(stateful, received, header, applicationJobOwner);
|
|
724
833
|
if (stateful !== undefined)
|
|
725
834
|
return stateful;
|
|
726
835
|
return this.processApplicationReceived(received, header, applicationJobOwner);
|
|
@@ -731,6 +840,12 @@ class RawServiceMeshRuntime {
|
|
|
731
840
|
return this.receiveProtocolFailure(error);
|
|
732
841
|
}
|
|
733
842
|
}
|
|
843
|
+
finishPendingProtocolReceive(pending) {
|
|
844
|
+
return pending.catch((error) => this.receiveProtocolFailure(error));
|
|
845
|
+
}
|
|
846
|
+
finishPendingStatefulReceive(pending, received, header, owner) {
|
|
847
|
+
return pending.then((result) => result ?? this.processApplicationReceived(received, header, owner), (error) => this.receiveProtocolFailure(error));
|
|
848
|
+
}
|
|
734
849
|
receiveProtocolFailure(error) {
|
|
735
850
|
if (error instanceof service_wire_m6a_codec_1.ServiceWireProtocolError)
|
|
736
851
|
return 'protocolError';
|
|
@@ -776,7 +891,7 @@ class RawServiceMeshRuntime {
|
|
|
776
891
|
}
|
|
777
892
|
else if (header.command === service_wire_m6a_codec_1.M6aServiceWireCommand.admit) {
|
|
778
893
|
this.controlSends.delete(helloKey);
|
|
779
|
-
this.
|
|
894
|
+
this.progressPeerAdmission(nowMs);
|
|
780
895
|
if (result === 'notRequired') {
|
|
781
896
|
this.retireNotRequiredExpectedPeer(received.sourceRid, descriptor.advertisedEndpoint);
|
|
782
897
|
}
|
|
@@ -860,13 +975,16 @@ class RawServiceMeshRuntime {
|
|
|
860
975
|
}
|
|
861
976
|
const job = applicationJobOwner.acquire('application');
|
|
862
977
|
return job instanceof Promise
|
|
863
|
-
?
|
|
978
|
+
? this.enqueuePendingOrdinaryRecord(job, received, owner, correlation)
|
|
864
979
|
: this.enqueueOrdinaryRecord(received, owner, correlation, job);
|
|
865
980
|
}
|
|
866
981
|
catch (error) {
|
|
867
982
|
return this.receiveProtocolFailure(error);
|
|
868
983
|
}
|
|
869
984
|
}
|
|
985
|
+
enqueuePendingOrdinaryRecord(pending, received, owner, correlation) {
|
|
986
|
+
return pending.then((permit) => this.enqueueOrdinaryRecord(received, owner, correlation, permit));
|
|
987
|
+
}
|
|
870
988
|
enqueueOrdinaryRecord(received, owner, correlation, applicationJob) {
|
|
871
989
|
const accepted = this.mailbox.tryEnqueue({
|
|
872
990
|
owner,
|
|
@@ -894,7 +1012,9 @@ class RawServiceMeshRuntime {
|
|
|
894
1012
|
return 'dropped';
|
|
895
1013
|
}
|
|
896
1014
|
expireOperations(nowMs, turnDeadlineMs) {
|
|
897
|
-
return this.operations.
|
|
1015
|
+
return this.requestOwner === undefined && nowMs >= this.operations.nextDeadlineMs()
|
|
1016
|
+
? this.operations.expire(nowMs, turnDeadlineMs)
|
|
1017
|
+
: 0;
|
|
898
1018
|
}
|
|
899
1019
|
get pendingOperationCount() {
|
|
900
1020
|
return this.operations.size;
|
|
@@ -908,26 +1028,33 @@ class RawServiceMeshRuntime {
|
|
|
908
1028
|
* ADMIT, which keeps the existing announce cadence.
|
|
909
1029
|
*/
|
|
910
1030
|
nextMaintenanceDeadlineMs(nowMs) {
|
|
911
|
-
this.
|
|
912
|
-
return Math.min(this.operations.nextDeadlineMs(), this.liveness.nextDeadlineMs());
|
|
1031
|
+
this.progressPeerAdmission(nowMs);
|
|
1032
|
+
return Math.min(this.requestOwner === undefined ? this.operations.nextDeadlineMs() : Infinity, this.liveness.nextDeadlineMs());
|
|
913
1033
|
}
|
|
914
|
-
|
|
1034
|
+
progressPeerAdmission(nowMs) {
|
|
915
1035
|
let pending = false;
|
|
916
1036
|
if (!this.closed && this.controlSends.size !== 0) {
|
|
917
1037
|
for (const nodeRoutingId of this.selectedRoutes.keys()) {
|
|
918
|
-
const
|
|
1038
|
+
const key = controlSendKey(nodeRoutingId, service_wire_m6a_codec_1.M6aServiceWireCommand.hello);
|
|
1039
|
+
const exchange = this.controlSends.get(key);
|
|
1040
|
+
// An unsent HELLO intent may resume after the host admission seal opens.
|
|
1041
|
+
// Only retransmission of submitted bytes waits for the management cadence.
|
|
919
1042
|
if (exchange?.current?.() === true) {
|
|
1043
|
+
if (exchange.hello === undefined)
|
|
1044
|
+
this.announcePeer(nodeRoutingId);
|
|
920
1045
|
pending = true;
|
|
921
|
-
break;
|
|
922
1046
|
}
|
|
923
1047
|
}
|
|
924
1048
|
}
|
|
925
1049
|
this.liveness.setAdmissionPending(pending, nowMs);
|
|
926
1050
|
}
|
|
927
1051
|
tickLiveness(nowMs = performance.now()) {
|
|
1052
|
+
this.progressPeerAdmission(nowMs);
|
|
928
1053
|
const admissionDue = this.liveness.tickAdmission(nowMs);
|
|
929
1054
|
const result = this.liveness.tick(nowMs);
|
|
930
1055
|
this.requireStarted();
|
|
1056
|
+
if (!admissionDue && result.probes.length === 0 && result.timedOutNodes.length === 0)
|
|
1057
|
+
return result;
|
|
931
1058
|
if (admissionDue)
|
|
932
1059
|
for (const nodeRoutingId of this.selectedRoutes.keys())
|
|
933
1060
|
void this.announcePeer(nodeRoutingId);
|
|
@@ -940,13 +1067,29 @@ class RawServiceMeshRuntime {
|
|
|
940
1067
|
];
|
|
941
1068
|
this.startControlSend(probe.nodeRoutingId, service_wire_m6a_codec_1.M6aServiceWireCommand.livenessProbe, () => this.submitControl(probe.nodeRoutingId, parts));
|
|
942
1069
|
}
|
|
1070
|
+
const failures = [];
|
|
943
1071
|
for (const nodeRoutingId of result.timedOutNodes) {
|
|
944
1072
|
const peer = this.topology.peer(nodeRoutingId);
|
|
945
1073
|
if (peer === undefined)
|
|
946
1074
|
continue;
|
|
947
|
-
|
|
948
|
-
|
|
1075
|
+
try {
|
|
1076
|
+
this.removePeer(peer, () => {
|
|
1077
|
+
try {
|
|
1078
|
+
this.requireStarted().disconnectRid(nodeRoutingId);
|
|
1079
|
+
}
|
|
1080
|
+
catch (error) {
|
|
1081
|
+
failures.push(error);
|
|
1082
|
+
}
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1085
|
+
catch (error) {
|
|
1086
|
+
failures.push(error);
|
|
1087
|
+
}
|
|
949
1088
|
}
|
|
1089
|
+
if (failures.length === 1)
|
|
1090
|
+
throw failures[0];
|
|
1091
|
+
if (failures.length > 1)
|
|
1092
|
+
throw new AggregateError(failures, 'Liveness peer cleanup failed.');
|
|
950
1093
|
return result;
|
|
951
1094
|
}
|
|
952
1095
|
/**
|
|
@@ -985,42 +1128,50 @@ class RawServiceMeshRuntime {
|
|
|
985
1128
|
this.selectedRoutes = observed;
|
|
986
1129
|
for (const nodeRoutingId of selected)
|
|
987
1130
|
this.notifyPeerRouteChanged(nodeRoutingId);
|
|
988
|
-
//
|
|
1131
|
+
// Selected routes begin admission before waiting for the management cadence.
|
|
989
1132
|
for (const nodeRoutingId of selected)
|
|
990
1133
|
await this.announcePeer(nodeRoutingId);
|
|
991
|
-
this.
|
|
1134
|
+
this.progressPeerAdmission(performance.now());
|
|
992
1135
|
return changes;
|
|
993
1136
|
}
|
|
994
1137
|
close() {
|
|
995
|
-
if (this.closed)
|
|
996
|
-
return;
|
|
997
|
-
this.closed = true;
|
|
998
|
-
this.applicationJobStop.abort(new Error('Raw service runtime application job admission stopped.'));
|
|
999
|
-
this.receivePermit?.releaseAfterInternalProcessing();
|
|
1000
|
-
this.receivePermit?.releaseStorage?.();
|
|
1001
|
-
this.receivePermit = undefined;
|
|
1002
|
-
for (const send of this.controlSends.values())
|
|
1003
|
-
delete send.next;
|
|
1004
|
-
this.controlSends.clear();
|
|
1005
|
-
this.mailbox.close();
|
|
1006
|
-
this.operations.close('Raw service runtime closed.');
|
|
1007
|
-
this.serviceIngress = undefined;
|
|
1008
|
-
const router = this.router;
|
|
1009
|
-
if (router !== undefined) {
|
|
1010
|
-
this.applicationJobQueue.unregisterReceiveFlowTarget?.(router);
|
|
1011
|
-
}
|
|
1012
1138
|
const host = this.host;
|
|
1013
|
-
if (host
|
|
1014
|
-
|
|
1015
|
-
this.router = undefined;
|
|
1139
|
+
if (this.closed && host === undefined)
|
|
1140
|
+
return;
|
|
1016
1141
|
this.host = undefined;
|
|
1142
|
+
try {
|
|
1143
|
+
if (!this.closed) {
|
|
1144
|
+
this.closed = true;
|
|
1145
|
+
this.applicationJobStop.abort((0, framework_errors_internal_1.createInternalFrameworkException)(framework_errors_internal_1.ZLinkFrameworkInternalErrorKind.RuntimeShutdown, 'Raw service runtime application job admission stopped.'));
|
|
1146
|
+
this.receivePermit?.releaseAfterInternalProcessing();
|
|
1147
|
+
this.receivePermit?.releaseStorage?.();
|
|
1148
|
+
this.receivePermit = undefined;
|
|
1149
|
+
for (const send of this.controlSends.values())
|
|
1150
|
+
delete send.next;
|
|
1151
|
+
this.controlSends.clear();
|
|
1152
|
+
this.mailbox.close();
|
|
1153
|
+
this.releaseOperations();
|
|
1154
|
+
this.serviceIngress = undefined;
|
|
1155
|
+
const router = this.router;
|
|
1156
|
+
if (router !== undefined) {
|
|
1157
|
+
this.applicationJobQueue.unregisterReceiveFlowTarget?.(router);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
if (host !== undefined)
|
|
1161
|
+
host.close();
|
|
1162
|
+
this.router = undefined;
|
|
1163
|
+
}
|
|
1164
|
+
catch (error) {
|
|
1165
|
+
this.host = host;
|
|
1166
|
+
throw error;
|
|
1167
|
+
}
|
|
1017
1168
|
}
|
|
1018
|
-
requestToTarget(targetNodeRoutingId, payload, timeoutMs, channelName, onAdmitted, observer, operationKind) {
|
|
1169
|
+
requestToTarget(targetNodeRoutingId, payload, timeoutMs, channelName, onAdmitted, observer, operationKind, requestOperation) {
|
|
1019
1170
|
const correlation = this.nextCorrelation++;
|
|
1020
1171
|
const header = channelName === undefined
|
|
1021
1172
|
? (0, service_wire_m6a_codec_1.encodeNodeRequestHeader)(correlation)
|
|
1022
1173
|
: (0, service_wire_m6a_codec_1.encodeChannelRequestHeader)(correlation, channelName);
|
|
1023
|
-
|
|
1174
|
+
let encodedPayload = this.applicationFrame(payload);
|
|
1024
1175
|
let selectedTargetNodeRoutingId = targetNodeRoutingId;
|
|
1025
1176
|
if (selectedTargetNodeRoutingId !== this.descriptor.nodeRoutingId &&
|
|
1026
1177
|
!this.isPeerRouteReady(selectedTargetNodeRoutingId)) {
|
|
@@ -1047,19 +1198,22 @@ class RawServiceMeshRuntime {
|
|
|
1047
1198
|
}
|
|
1048
1199
|
}
|
|
1049
1200
|
if (selectedTargetNodeRoutingId === this.descriptor.nodeRoutingId) {
|
|
1201
|
+
encodedPayload = (0, payload_slab_1.copyPayloadBytes)(encodedPayload);
|
|
1050
1202
|
// The local admission path aborts its capacity wait on the terminal
|
|
1051
1203
|
// Promise, so a local request always keeps the Promise entry.
|
|
1052
|
-
const pending =
|
|
1204
|
+
const pending = requestOperation === undefined
|
|
1205
|
+
? this.operations.register(timeoutMs)
|
|
1206
|
+
: this.registerRequest(timeoutMs, observer, operationKind, requestOperation);
|
|
1053
1207
|
const parts = [header, encodedPayload];
|
|
1054
1208
|
const capacityStop = new AbortController();
|
|
1055
1209
|
void pending.promise.finally(() => capacityStop.abort()).catch(() => undefined);
|
|
1056
1210
|
void (async () => {
|
|
1057
1211
|
const applicationJobOwner = await this.reserveLocalIngress(capacityStop.signal);
|
|
1058
1212
|
try {
|
|
1059
|
-
if (!
|
|
1213
|
+
if (!pending.isPending())
|
|
1060
1214
|
return;
|
|
1061
1215
|
const applicationJob = await applicationJobOwner.acquire('application', capacityStop.signal);
|
|
1062
|
-
if (!
|
|
1216
|
+
if (!pending.isPending()) {
|
|
1063
1217
|
applicationJob.close();
|
|
1064
1218
|
return;
|
|
1065
1219
|
}
|
|
@@ -1069,19 +1223,19 @@ class RawServiceMeshRuntime {
|
|
|
1069
1223
|
parts,
|
|
1070
1224
|
sourceRoutingId: this.descriptor.nodeRoutingId,
|
|
1071
1225
|
correlation,
|
|
1072
|
-
localReply: (terminalResult, failureCode, reply) => this.
|
|
1226
|
+
localReply: (terminalResult, failureCode, reply) => this.completeRequest(pending, {
|
|
1073
1227
|
terminalResult,
|
|
1074
1228
|
failureCode,
|
|
1075
1229
|
...(reply === undefined ? {} : { payload: reply })
|
|
1076
|
-
}),
|
|
1230
|
+
}, requestOperation === undefined ? undefined : observer, operationKind),
|
|
1077
1231
|
applicationJob
|
|
1078
1232
|
});
|
|
1079
1233
|
if (!accepted) {
|
|
1080
1234
|
applicationJob.close();
|
|
1081
|
-
this.
|
|
1235
|
+
this.completeRequest(pending, {
|
|
1082
1236
|
terminalResult: runtime_values_1.RequestResult.NotConnected,
|
|
1083
1237
|
failureCode: 0
|
|
1084
|
-
});
|
|
1238
|
+
}, requestOperation === undefined ? undefined : observer, operationKind);
|
|
1085
1239
|
}
|
|
1086
1240
|
else {
|
|
1087
1241
|
onAdmitted?.();
|
|
@@ -1090,31 +1244,22 @@ class RawServiceMeshRuntime {
|
|
|
1090
1244
|
finally {
|
|
1091
1245
|
applicationJobOwner.close();
|
|
1092
1246
|
}
|
|
1093
|
-
})().catch((error) => this.
|
|
1247
|
+
})().catch((error) => this.failRequest(pending, error, requestOperation === undefined ? undefined : observer, operationKind));
|
|
1094
1248
|
return pending;
|
|
1095
1249
|
}
|
|
1096
|
-
const pending = this.registerRequest(timeoutMs, observer, operationKind);
|
|
1097
|
-
const selectedPeer = this.topology.
|
|
1098
|
-
if (selectedPeer === undefined
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
// route can carry the request is Core's REQUEST result.
|
|
1250
|
+
const pending = this.registerRequest(timeoutMs, observer, operationKind, requestOperation);
|
|
1251
|
+
const selectedPeer = this.topology.readyPeer(selectedTargetNodeRoutingId);
|
|
1252
|
+
if (selectedPeer === undefined &&
|
|
1253
|
+
!this.expectedPeers.has(selectedTargetNodeRoutingId) &&
|
|
1254
|
+
this.topology.peer(selectedTargetNodeRoutingId) === undefined) {
|
|
1102
1255
|
this.completeRequest(pending, {
|
|
1103
1256
|
terminalResult: runtime_values_1.RequestResult.NotFound,
|
|
1104
1257
|
failureCode: REQUEST_TARGET_NOT_FOUND_FAILURE_CODE
|
|
1105
|
-
});
|
|
1258
|
+
}, requestOperation === undefined ? undefined : observer, operationKind);
|
|
1106
1259
|
return pending;
|
|
1107
1260
|
}
|
|
1108
1261
|
const parts = [header, encodedPayload];
|
|
1109
|
-
|
|
1110
|
-
try {
|
|
1111
|
-
request = this.requireStarted().request(selectedTargetNodeRoutingId, parts, timeoutMs, selectedPeer.liveness?.recordReceived, onAdmitted);
|
|
1112
|
-
}
|
|
1113
|
-
catch (error) {
|
|
1114
|
-
this.failRequest(pending, error);
|
|
1115
|
-
return pending;
|
|
1116
|
-
}
|
|
1117
|
-
void request.then((replyParts) => {
|
|
1262
|
+
const completed = (replyParts) => {
|
|
1118
1263
|
try {
|
|
1119
1264
|
if (replyParts.length < 1 || replyParts.length > 2) {
|
|
1120
1265
|
throw new service_wire_m6a_codec_1.ServiceWireProtocolError('Invalid reply parts.');
|
|
@@ -1135,16 +1280,37 @@ class RawServiceMeshRuntime {
|
|
|
1135
1280
|
terminalResult: reply.terminalResult,
|
|
1136
1281
|
failureCode: reply.failureCode
|
|
1137
1282
|
};
|
|
1138
|
-
|
|
1283
|
+
const value = reply.terminalResult === 0
|
|
1139
1284
|
? { ...result, payload: (0, service_wire_m6a_codec_1.decodeApplicationPayloadView)(replyParts[1]) }
|
|
1140
|
-
: result
|
|
1285
|
+
: result;
|
|
1286
|
+
if (requestOperation !== undefined && observer !== undefined)
|
|
1287
|
+
observer.operationCompleted(pending.id, value, operationKind);
|
|
1288
|
+
else
|
|
1289
|
+
pending.reply(value);
|
|
1141
1290
|
}
|
|
1142
1291
|
catch (error) {
|
|
1143
|
-
this.
|
|
1292
|
+
this.failRequest(pending, error, requestOperation === undefined ? undefined : observer, operationKind);
|
|
1144
1293
|
}
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1294
|
+
};
|
|
1295
|
+
const failed = (error) => this.failRequest(pending, error, requestOperation === undefined ? undefined : observer, operationKind);
|
|
1296
|
+
if (selectedPeer !== undefined) {
|
|
1297
|
+
try {
|
|
1298
|
+
this.requireStarted().request(selectedTargetNodeRoutingId, parts, (0, request_deadline_1.remainingRequestTimeout)('Request', pending.deadlineMs), completed, failed, selectedPeer.liveness?.recordReceived, onAdmitted, pending);
|
|
1299
|
+
}
|
|
1300
|
+
catch (error) {
|
|
1301
|
+
failed(error);
|
|
1302
|
+
}
|
|
1303
|
+
return pending;
|
|
1304
|
+
}
|
|
1305
|
+
(0, durable_service_request_1.admitServiceRequest)(this, selectedTargetNodeRoutingId, pending, (remaining, finished) => {
|
|
1306
|
+
this.requireStarted().request(selectedTargetNodeRoutingId, parts, remaining, (reply) => {
|
|
1307
|
+
finished();
|
|
1308
|
+
completed(reply);
|
|
1309
|
+
}, (error) => {
|
|
1310
|
+
finished();
|
|
1311
|
+
failed(error);
|
|
1312
|
+
}, this.topology.admittedPeer(selectedTargetNodeRoutingId)?.liveness?.recordReceived, onAdmitted, pending);
|
|
1313
|
+
}, failed);
|
|
1148
1314
|
return pending;
|
|
1149
1315
|
}
|
|
1150
1316
|
/**
|
|
@@ -1155,10 +1321,10 @@ class RawServiceMeshRuntime {
|
|
|
1155
1321
|
return Buffer.isBuffer(payload) ? payload : (0, service_wire_m6a_codec_1.encodeApplicationPayload)(payload);
|
|
1156
1322
|
}
|
|
1157
1323
|
applicationPayload(payload) {
|
|
1158
|
-
return Buffer.isBuffer(payload) ? (0, service_wire_m6a_codec_1.
|
|
1324
|
+
return Buffer.isBuffer(payload) ? (0, service_wire_m6a_codec_1.decodeApplicationPayload)(payload) : payload;
|
|
1159
1325
|
}
|
|
1160
1326
|
admitPeer(descriptor, connectionId, nowMs, expected, command = service_wire_m6a_codec_1.M6aServiceWireCommand.hello, descriptorBytes) {
|
|
1161
|
-
const previous = this.topology.
|
|
1327
|
+
const previous = this.topology.admittedPeer(descriptor.nodeRoutingId);
|
|
1162
1328
|
const topologyConnectionId = typeof connectionId === 'bigint' ? routeConnectionId(connectionId) : connectionId;
|
|
1163
1329
|
const result = this.topology.admit(descriptor, topologyConnectionId, expected, () => {
|
|
1164
1330
|
const admission = this.liveness.admit(descriptor.nodeRoutingId, connectionId, nowMs);
|
|
@@ -1171,7 +1337,11 @@ class RawServiceMeshRuntime {
|
|
|
1171
1337
|
if (result === 'notRequired' && previous !== undefined) {
|
|
1172
1338
|
this.liveness.disconnect(descriptor.nodeRoutingId, previous.liveness?.connectionId ?? previous.connectionId);
|
|
1173
1339
|
}
|
|
1174
|
-
if (result === 'admitted'
|
|
1340
|
+
if (result === 'admitted' &&
|
|
1341
|
+
(previous?.connectionId !== topologyConnectionId ||
|
|
1342
|
+
previous.descriptor.lifecycleGeneration !== descriptor.lifecycleGeneration ||
|
|
1343
|
+
previous.remoteAdmitReceived !==
|
|
1344
|
+
this.topology.admittedPeer(descriptor.nodeRoutingId)?.remoteAdmitReceived))
|
|
1175
1345
|
this.notifyPeerRouteChanged(descriptor.nodeRoutingId);
|
|
1176
1346
|
return result;
|
|
1177
1347
|
}
|
|
@@ -1204,10 +1374,16 @@ class RawServiceMeshRuntime {
|
|
|
1204
1374
|
});
|
|
1205
1375
|
this.endpointOnlyPeers.delete(endpoint);
|
|
1206
1376
|
}
|
|
1207
|
-
removePeer(peer) {
|
|
1377
|
+
removePeer(peer, disconnectPhysical) {
|
|
1208
1378
|
this.topology.disconnect(peer.descriptor.nodeRoutingId, peer.connectionId);
|
|
1209
1379
|
this.liveness.disconnect(peer.descriptor.nodeRoutingId, peer.liveness?.connectionId ?? peer.connectionId);
|
|
1210
|
-
|
|
1380
|
+
try {
|
|
1381
|
+
disconnectPhysical?.();
|
|
1382
|
+
}
|
|
1383
|
+
finally {
|
|
1384
|
+
// The logical admission has ended even when the physical disconnect reports a failure.
|
|
1385
|
+
this.onPeerDisconnected?.(peer.descriptor.nodeRoutingId, peer.descriptor.advertisedEndpoint, peer.descriptor.lifecycleGeneration);
|
|
1386
|
+
}
|
|
1211
1387
|
}
|
|
1212
1388
|
requireStarted() {
|
|
1213
1389
|
if (this.router === undefined)
|
|
@@ -1234,9 +1410,7 @@ class RawServiceMeshRuntime {
|
|
|
1234
1410
|
if (command === service_wire_m6a_codec_1.M6aServiceWireCommand.hello)
|
|
1235
1411
|
this.liveness.setAdmissionPending(true, performance.now());
|
|
1236
1412
|
const existing = this.controlSends.get(key);
|
|
1237
|
-
if (existing !== undefined
|
|
1238
|
-
existing.task !== undefined &&
|
|
1239
|
-
(command !== service_wire_m6a_codec_1.M6aServiceWireCommand.hello || existing.current?.() === true)) {
|
|
1413
|
+
if (existing?.task !== undefined) {
|
|
1240
1414
|
if (command !== service_wire_m6a_codec_1.M6aServiceWireCommand.hello) {
|
|
1241
1415
|
existing.next = attempt;
|
|
1242
1416
|
existing.current = current;
|
|
@@ -1254,7 +1428,7 @@ class RawServiceMeshRuntime {
|
|
|
1254
1428
|
const completeSend = () => {
|
|
1255
1429
|
if (owner.controlSends.get(key) !== state)
|
|
1256
1430
|
return;
|
|
1257
|
-
if (hello !== undefined
|
|
1431
|
+
if (hello !== undefined)
|
|
1258
1432
|
delete state.task;
|
|
1259
1433
|
else
|
|
1260
1434
|
owner.controlSends.delete(key);
|
|
@@ -1297,6 +1471,8 @@ class RawServiceMeshRuntime {
|
|
|
1297
1471
|
throw failure.error;
|
|
1298
1472
|
}
|
|
1299
1473
|
send(targetNodeRoutingId, parts) {
|
|
1474
|
+
if (!this.isPeerRouteReady(targetNodeRoutingId))
|
|
1475
|
+
return false;
|
|
1300
1476
|
try {
|
|
1301
1477
|
const submission = this.requireStarted().submitSend(targetNodeRoutingId, parts);
|
|
1302
1478
|
if (submission.result === runtime_values_1.SubmitResult.Ok)
|
|
@@ -1317,6 +1493,9 @@ class RawServiceMeshRuntime {
|
|
|
1317
1493
|
}
|
|
1318
1494
|
}
|
|
1319
1495
|
exports.RawServiceMeshRuntime = RawServiceMeshRuntime;
|
|
1496
|
+
function channelSendSubmitResult(accepted) {
|
|
1497
|
+
return accepted ? runtime_values_1.SubmitResult.Ok : runtime_values_1.SubmitResult.NotConnected;
|
|
1498
|
+
}
|
|
1320
1499
|
function controlSendKey(target, command) {
|
|
1321
1500
|
return `${command}:${target}`;
|
|
1322
1501
|
}
|