@zlink-systems/framework 0.30.0 → 0.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +150 -68
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
- package/dist/contracts/Channels/Calls.d.ts +2 -1
- package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
- package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
- package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
- package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
- package/dist/contracts/Common/encoded-payload-storage.js +5 -2
- package/dist/contracts/Configuration/Builders.d.ts +1 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
- package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
- package/dist/contracts/Handlers/Attributes.d.ts +5 -13
- package/dist/contracts/Handlers/Attributes.js +7 -11
- package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
- package/dist/contracts/Handlers/JsonContract.js +4 -153
- package/dist/contracts/Locations/Rows.d.ts +2 -0
- package/dist/contracts/Spots/Contracts.d.ts +6 -1
- package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
- package/dist/nest-integration.d.ts +1 -1
- package/dist/nest-integration.js +2 -1
- package/dist/runtime/abort.d.ts +5 -0
- package/dist/runtime/abort.js +10 -0
- package/dist/runtime/actors/actor-authority-publication.js +3 -2
- package/dist/runtime/actors/actor-client.d.ts +1 -2
- package/dist/runtime/actors/actor-client.js +52 -57
- package/dist/runtime/actors/actor-context.d.ts +2 -0
- package/dist/runtime/actors/actor-context.js +46 -9
- package/dist/runtime/actors/actor-handoff.d.ts +8 -4
- package/dist/runtime/actors/actor-handoff.js +219 -92
- package/dist/runtime/actors/actor-join-relocation.d.ts +3 -0
- package/dist/runtime/actors/actor-local-native-join.js +13 -12
- package/dist/runtime/actors/actor-mailbox.js +27 -1
- package/dist/runtime/actors/actor-remote-joiner.js +3 -1
- package/dist/runtime/actors/actor-remote-wire.js +15 -0
- package/dist/runtime/actors/actor-reply.d.ts +4 -0
- package/dist/runtime/actors/actor-reply.js +29 -0
- package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
- package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
- package/dist/runtime/actors/actor-runtime-state.js +2 -20
- package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
- package/dist/runtime/actors/index.d.ts +8 -3
- package/dist/runtime/actors/index.js +55 -27
- package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
- package/dist/runtime/actors/session-disconnected-wire.js +48 -0
- package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
- package/dist/runtime/admission.d.ts +9 -1
- package/dist/runtime/admission.js +56 -23
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +6 -8
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +39 -22
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +15 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +61 -20
- package/dist/runtime/application-jobs/contracts.d.ts +12 -1
- package/dist/runtime/backend/contracts/index.d.ts +37 -12
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
- package/dist/runtime/backend/mesh-completion-table.d.ts +9 -1
- package/dist/runtime/backend/mesh-completion-table.js +154 -49
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +28 -1
- package/dist/runtime/backend/mesh-dispatch-pump.js +208 -101
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
- package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -9
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
- package/dist/runtime/backend/node/node-raw-binding-port.js +124 -72
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +46 -13
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +181 -164
- package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +11 -11
- package/dist/runtime/backend/raw-binding-port.d.ts +2 -2
- package/dist/runtime/backend/runtime-message.d.ts +1 -0
- package/dist/runtime/backend/runtime-message.js +5 -0
- package/dist/runtime/backend/runtime-values.d.ts +1 -0
- package/dist/runtime/backend/runtime-values.js +2 -1
- package/dist/runtime/channels/channel-clients.d.ts +2 -0
- package/dist/runtime/channels/channel-clients.js +75 -23
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +25 -5
- package/dist/runtime/channels/channel-dispatch-pipeline.js +111 -56
- package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
- package/dist/runtime/channels/channel-dispatch-services.js +45 -0
- package/dist/runtime/channels/channel-dispatchers.d.ts +4 -3
- package/dist/runtime/channels/channel-dispatchers.js +62 -54
- package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
- package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
- package/dist/runtime/channels/channel-envelope.d.ts +2 -0
- package/dist/runtime/channels/channel-envelope.js +146 -28
- package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
- package/dist/runtime/channels/channel-runtime-manager.d.ts +9 -8
- package/dist/runtime/channels/channel-runtime-manager.js +16 -16
- package/dist/runtime/channels/channel-transports.d.ts +18 -16
- package/dist/runtime/channels/channel-transports.js +77 -58
- package/dist/runtime/channels/client-server-location-runtime.js +5 -4
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/fanout-location-runtime.js +3 -3
- package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
- package/dist/runtime/channels/local-spot-route-transport.js +2 -1
- package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
- package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
- package/dist/runtime/channels/source-spot-router.d.ts +2 -2
- package/dist/runtime/channels/source-spot-router.js +4 -4
- package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
- package/dist/runtime/channels/spot-node-route-transport.js +4 -4
- package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
- package/dist/runtime/diagnostics/flow-context.js +19 -7
- package/dist/runtime/diagnostics/index.js +4 -9
- package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
- package/dist/runtime/diagnostics/message-flow.js +35 -5
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
- package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
- package/dist/runtime/execution/index.d.ts +4 -2
- package/dist/runtime/execution/index.js +33 -10
- package/dist/runtime/execution/serial-execution-queue.d.ts +5 -0
- package/dist/runtime/execution/serial-execution-queue.js +22 -2
- package/dist/runtime/execution/state-lane.d.ts +2 -0
- package/dist/runtime/execution/state-lane.js +5 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
- package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
- package/dist/runtime/foundation/durable-service-request.js +98 -0
- package/dist/runtime/foundation/operation-identity.d.ts +1 -0
- package/dist/runtime/foundation/operation-identity.js +5 -1
- package/dist/runtime/foundation/operation-registry.d.ts +25 -1
- package/dist/runtime/foundation/operation-registry.js +86 -18
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +61 -8
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +486 -266
- package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
- package/dist/runtime/foundation/service-liveness-registry.js +38 -0
- package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +3 -3
- package/dist/runtime/foundation/service-relocation-object-owner.js +48 -34
- package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
- package/dist/runtime/foundation/service-relocation-runtime.js +20 -4
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +10 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
- package/dist/runtime/foundation/service-stateful-registry.js +24 -26
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +75 -9
- package/dist/runtime/foundation/service-stateful-runtime.js +486 -218
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -6
- package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
- package/dist/runtime/foundation/service-topology-registry.d.ts +12 -2
- package/dist/runtime/foundation/service-topology-registry.js +61 -27
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
- package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +13 -3
- package/dist/runtime/foundation/service-wire-m6a-codec.js +189 -78
- package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
- package/dist/runtime/handlers/handler-instance-scope.js +54 -11
- package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
- package/dist/runtime/host/actor-packet-relay.js +59 -72
- package/dist/runtime/host/actor-placement-coordinator.js +25 -8
- package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
- package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
- package/dist/runtime/host/actor-transfer-runtime.js +85 -331
- package/dist/runtime/host/application-job-queue.d.ts +40 -7
- package/dist/runtime/host/application-job-queue.js +137 -42
- package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
- package/dist/runtime/host/entry-actor-runtime.js +3 -0
- package/dist/runtime/host/index.d.ts +12 -2
- package/dist/runtime/host/index.js +300 -202
- package/dist/runtime/host/location-runtime-owner.js +2 -6
- package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
- package/dist/runtime/host/mesh-router-resolver.js +14 -6
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
- package/dist/runtime/host/remote-bound-session-relay.js +73 -208
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
- package/dist/runtime/host/route-mesh-runtime.js +6 -4
- package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
- package/dist/runtime/host/runtime-shutdown.js +3 -2
- package/dist/runtime/host/service-relocation-control.d.ts +1 -0
- package/dist/runtime/host/service-relocation-control.js +10 -4
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +22 -14
- package/dist/runtime/host/service-relocation-host-runtime.js +754 -599
- package/dist/runtime/host/spot-address-transport.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.js +16 -7
- package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
- package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
- package/dist/runtime/locations/actor-location-claims.js +34 -19
- package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
- package/dist/runtime/locations/auto-connect-loop.js +22 -14
- package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
- package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
- package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
- package/dist/runtime/locations/descriptor-publication.js +11 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
- package/dist/runtime/locations/in-memory-authority-store.js +56 -19
- package/dist/runtime/locations/in-memory-location-store.js +1 -10
- package/dist/runtime/locations/index.d.ts +1 -0
- package/dist/runtime/locations/index.js +1 -0
- package/dist/runtime/locations/lease-tracker.js +1 -6
- package/dist/runtime/locations/lifecycle.d.ts +1 -2
- package/dist/runtime/locations/lifecycle.js +2 -5
- package/dist/runtime/locations/location-store-repository.d.ts +51 -1
- package/dist/runtime/locations/location-store-repository.js +363 -139
- package/dist/runtime/locations/relocation-blob.d.ts +18 -1
- package/dist/runtime/locations/relocation-blob.js +52 -1
- package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
- package/dist/runtime/locations/request-source-resolver.js +80 -0
- package/dist/runtime/locations/resolvers.js +1 -1
- package/dist/runtime/locations/runtime.d.ts +7 -3
- package/dist/runtime/locations/runtime.js +61 -53
- package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
- package/dist/runtime/messaging/framework-json-v1.js +38 -294
- package/dist/runtime/messaging/packet-name.d.ts +1 -1
- package/dist/runtime/messaging/packet-name.js +8 -24
- package/dist/runtime/messaging/payload-codec.d.ts +7 -1
- package/dist/runtime/messaging/payload-codec.js +7 -6
- package/dist/runtime/messaging/request-result.d.ts +2 -0
- package/dist/runtime/messaging/request-result.js +57 -0
- package/dist/runtime/messaging/submission-result.d.ts +1 -0
- package/dist/runtime/messaging/submission-result.js +5 -2
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +34 -1
- package/dist/runtime/protocol/service_wire_codec.generated.js +229 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +16 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +37 -8
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +7 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +36 -21
- package/dist/runtime/spots/index.d.ts +21 -11
- package/dist/runtime/spots/index.js +243 -178
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +21 -11
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +7 -7
- package/dist/runtime/spots/spot-activation.d.ts +7 -3
- package/dist/runtime/spots/spot-activation.js +140 -52
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
- package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-membership.js +0 -8
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
- package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
- package/dist/runtime/spots/spot-entry-activation.js +20 -11
- package/dist/runtime/spots/spot-handler-registry.d.ts +7 -4
- package/dist/runtime/spots/spot-handler-registry.js +24 -10
- package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
- package/dist/runtime/spots/spot-manager-public.js +2 -2
- package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
- package/dist/runtime/spots/spot-node-autoconnect.js +22 -42
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
- package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
- package/dist/runtime/spots/spot-outbound.d.ts +3 -0
- package/dist/runtime/spots/spot-outbound.js +27 -18
- package/dist/runtime/spots/spot-remote-codec.js +5 -1
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +1 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
- package/dist/runtime/spots/spot-serial-executor.js +61 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
- package/dist/runtime/spots/spot-subscription-dispatch.js +1 -4
- package/dist/runtime/spots/spot-timer.d.ts +57 -5
- package/dist/runtime/spots/spot-timer.js +288 -103
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
- package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
- package/dist/runtime/streams/bound-session-service.d.ts +1 -1
- package/dist/runtime/streams/bound-session-service.js +6 -11
- package/dist/runtime/streams/index.d.ts +3 -2
- package/dist/runtime/streams/index.js +6 -4
- package/dist/runtime/streams/managed-stream.js +3 -2
- package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
- package/dist/runtime/streams/session-actor-coordinator.js +15 -32
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
- package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
- package/dist/runtime/streams/stream-session-runtime.js +14 -31
- package/dist/runtime/workers/index.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
- package/src/contracts/Channels/Calls.ts +2 -1
- package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
- package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
- package/src/contracts/Common/encoded-payload-storage.ts +6 -3
- package/src/contracts/Configuration/Builders.ts +4 -1
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
- package/src/contracts/Handlers/Attributes.ts +14 -21
- package/src/contracts/Handlers/JsonContract.ts +8 -216
- package/src/contracts/Locations/Rows.ts +2 -0
- package/src/contracts/Spots/Contracts.ts +10 -1
- package/src/contracts/Spots/ZLinkSpot.ts +3 -3
- package/src/nest-integration.ts +1 -0
- package/src/runtime/abort.ts +12 -0
- package/src/runtime/actors/actor-authority-publication.ts +3 -2
- package/src/runtime/actors/actor-client.ts +100 -85
- package/src/runtime/actors/actor-context.ts +49 -9
- package/src/runtime/actors/actor-handoff.ts +291 -110
- package/src/runtime/actors/actor-join-relocation.ts +3 -0
- package/src/runtime/actors/actor-local-native-join.ts +21 -26
- package/src/runtime/actors/actor-mailbox.ts +40 -2
- package/src/runtime/actors/actor-remote-joiner.ts +6 -1
- package/src/runtime/actors/actor-remote-wire.ts +17 -0
- package/src/runtime/actors/actor-reply.ts +42 -0
- package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
- package/src/runtime/actors/actor-routed-json-request.ts +10 -2
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
- package/src/runtime/actors/actor-runtime-state.ts +2 -20
- package/src/runtime/actors/actor-source-transfer.ts +1 -34
- package/src/runtime/actors/index.ts +60 -32
- package/src/runtime/actors/session-disconnected-wire.ts +66 -0
- package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
- package/src/runtime/admission.ts +69 -21
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +41 -25
- package/src/runtime/application-jobs/application-job-queue-scope.ts +83 -22
- package/src/runtime/application-jobs/contracts.ts +16 -1
- package/src/runtime/backend/contracts/index.ts +92 -18
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
- package/src/runtime/backend/mesh-completion-table.ts +160 -57
- package/src/runtime/backend/mesh-dispatch-pump.ts +237 -108
- package/src/runtime/backend/node/node-backend-adapter-support.ts +17 -8
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
- package/src/runtime/backend/node/node-raw-binding-port.ts +148 -85
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +315 -201
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +26 -11
- package/src/runtime/backend/raw-binding-port.ts +7 -2
- package/src/runtime/backend/runtime-message.ts +6 -0
- package/src/runtime/backend/runtime-values.ts +1 -0
- package/src/runtime/channels/channel-clients.ts +132 -58
- package/src/runtime/channels/channel-dispatch-pipeline.ts +198 -114
- package/src/runtime/channels/channel-dispatch-services.ts +69 -1
- package/src/runtime/channels/channel-dispatchers.ts +136 -90
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
- package/src/runtime/channels/channel-envelope.ts +225 -31
- package/src/runtime/channels/channel-outbound-operations.ts +22 -8
- package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
- package/src/runtime/channels/channel-runtime-manager.ts +41 -17
- package/src/runtime/channels/channel-transports.ts +171 -112
- package/src/runtime/channels/client-server-location-runtime.ts +11 -10
- package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
- package/src/runtime/channels/fanout-location-runtime.ts +17 -9
- package/src/runtime/channels/local-spot-route-transport.ts +3 -1
- package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
- package/src/runtime/channels/source-spot-router.ts +8 -4
- package/src/runtime/channels/spot-node-route-transport.ts +8 -4
- package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
- package/src/runtime/diagnostics/flow-context.ts +20 -7
- package/src/runtime/diagnostics/index.ts +1 -7
- package/src/runtime/diagnostics/message-flow.ts +47 -9
- package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
- package/src/runtime/execution/index.ts +40 -14
- package/src/runtime/execution/serial-execution-queue.ts +33 -4
- package/src/runtime/execution/state-lane.ts +7 -0
- package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
- package/src/runtime/foundation/durable-service-request.ts +137 -0
- package/src/runtime/foundation/operation-identity.ts +5 -1
- package/src/runtime/foundation/operation-registry.ts +98 -20
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +704 -336
- package/src/runtime/foundation/service-liveness-registry.ts +39 -0
- package/src/runtime/foundation/service-mailbox.ts +8 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
- package/src/runtime/foundation/service-relocation-object-owner.ts +55 -36
- package/src/runtime/foundation/service-relocation-runtime.ts +25 -4
- package/src/runtime/foundation/service-runtime-contracts.ts +19 -2
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
- package/src/runtime/foundation/service-stateful-registry.ts +38 -35
- package/src/runtime/foundation/service-stateful-runtime.ts +732 -275
- package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -16
- package/src/runtime/foundation/service-topology-registry.ts +91 -36
- package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +231 -76
- package/src/runtime/handlers/handler-instance-scope.ts +67 -16
- package/src/runtime/host/actor-packet-relay.ts +113 -94
- package/src/runtime/host/actor-placement-coordinator.ts +31 -8
- package/src/runtime/host/actor-runtime-options-factory.ts +13 -2
- package/src/runtime/host/actor-transfer-runtime.ts +104 -430
- package/src/runtime/host/application-job-queue.ts +160 -41
- package/src/runtime/host/entry-actor-runtime.ts +4 -0
- package/src/runtime/host/index.ts +473 -271
- package/src/runtime/host/location-runtime-owner.ts +2 -6
- package/src/runtime/host/mesh-router-resolver.ts +13 -5
- package/src/runtime/host/remote-bound-session-relay.ts +88 -271
- package/src/runtime/host/route-mesh-runtime.ts +12 -6
- package/src/runtime/host/runtime-shutdown.ts +15 -4
- package/src/runtime/host/service-relocation-control.ts +11 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +1092 -759
- package/src/runtime/host/spot-address-transport.ts +4 -2
- package/src/runtime/host/spot-runtime-options-factory.ts +20 -7
- package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
- package/src/runtime/locations/actor-location-claims.ts +52 -30
- package/src/runtime/locations/auto-connect-loop.ts +22 -14
- package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
- package/src/runtime/locations/auto-connect-types.ts +0 -1
- package/src/runtime/locations/descriptor-publication.ts +7 -0
- package/src/runtime/locations/domain-store-contract.ts +5 -0
- package/src/runtime/locations/in-memory-authority-store.ts +85 -23
- package/src/runtime/locations/in-memory-location-store.ts +1 -12
- package/src/runtime/locations/index.ts +1 -0
- package/src/runtime/locations/lease-tracker.ts +2 -9
- package/src/runtime/locations/lifecycle.ts +8 -26
- package/src/runtime/locations/location-store-repository.ts +628 -152
- package/src/runtime/locations/relocation-blob.ts +75 -1
- package/src/runtime/locations/request-source-resolver.ts +138 -0
- package/src/runtime/locations/resolvers.ts +2 -2
- package/src/runtime/locations/runtime.ts +98 -64
- package/src/runtime/messaging/framework-json-v1.ts +5 -325
- package/src/runtime/messaging/packet-name.ts +5 -25
- package/src/runtime/messaging/payload-codec.ts +8 -11
- package/src/runtime/messaging/request-result.ts +62 -0
- package/src/runtime/messaging/submission-result.ts +5 -1
- package/src/runtime/protocol/service_wire_codec.generated.ts +218 -5
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +16 -13
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +46 -25
- package/src/runtime/spots/index.ts +389 -283
- package/src/runtime/spots/spot-activation-registry.ts +25 -13
- package/src/runtime/spots/spot-activation-state.ts +12 -19
- package/src/runtime/spots/spot-activation.ts +198 -96
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
- package/src/runtime/spots/spot-actor-membership.ts +0 -15
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
- package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
- package/src/runtime/spots/spot-entry-activation.ts +33 -21
- package/src/runtime/spots/spot-handler-registry.ts +56 -12
- package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
- package/src/runtime/spots/spot-manager-public.ts +2 -2
- package/src/runtime/spots/spot-node-autoconnect.ts +28 -47
- package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
- package/src/runtime/spots/spot-outbound.ts +39 -19
- package/src/runtime/spots/spot-remote-codec.ts +9 -2
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
- package/src/runtime/spots/spot-runtime-ports.ts +1 -1
- package/src/runtime/spots/spot-serial-executor.ts +97 -25
- package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
- package/src/runtime/spots/spot-subscription-dispatch.ts +1 -4
- package/src/runtime/spots/spot-timer.ts +418 -158
- package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
- package/src/runtime/streams/bound-session-service.ts +7 -10
- package/src/runtime/streams/index.ts +12 -6
- package/src/runtime/streams/managed-stream.ts +4 -2
- package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
- package/src/runtime/streams/session-actor-coordinator.ts +39 -88
- package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
- package/src/runtime/streams/stream-session-runtime.ts +13 -34
- package/src/runtime/workers/index.ts +1 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { ZLinkConfigurationException } from '../configuration';
|
|
3
2
|
import { isAbortError } from '../abort';
|
|
4
3
|
import {
|
|
5
4
|
ZLinkFrameworkInternalErrorKind,
|
|
@@ -53,6 +52,7 @@ export class ZLinkSpotSerialTurn {
|
|
|
53
52
|
private suspendedResolve: (() => void) | undefined;
|
|
54
53
|
private suspendedPromise: Promise<void> | undefined;
|
|
55
54
|
private suspendSignaled = false;
|
|
55
|
+
private yieldUsed = false;
|
|
56
56
|
private owner: Promise<unknown> | undefined;
|
|
57
57
|
private frameworkOperationsBlocked = false;
|
|
58
58
|
|
|
@@ -115,26 +115,41 @@ export class ZLinkSpotSerialTurn {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
resetSuspension(): void {
|
|
118
|
+
this.yieldUsed = false;
|
|
118
119
|
this.suspendSignaled = false;
|
|
119
120
|
this.suspendedResolve = undefined;
|
|
120
121
|
this.suspendedPromise = undefined;
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
admitYield(): void {
|
|
125
|
+
const current = spotSerialTurnStorage.getStore();
|
|
126
|
+
if (
|
|
127
|
+
current?.turn !== this ||
|
|
128
|
+
!this.yieldAllowed ||
|
|
129
|
+
!current.executor.isActiveTurn(this, current.turnId) ||
|
|
130
|
+
this.yieldUsed
|
|
131
|
+
) {
|
|
132
|
+
throw createInternalFrameworkException(
|
|
133
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
134
|
+
'Yield requires the current SpotWide application turn and may be used only once per turn.'
|
|
127
135
|
);
|
|
128
136
|
}
|
|
137
|
+
this.yieldUsed = true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async yieldPromise<T>(pending: Promise<T>): Promise<T> {
|
|
141
|
+
this.admitYield();
|
|
129
142
|
return await this.yieldFrameworkPromise(pending);
|
|
130
143
|
}
|
|
131
144
|
|
|
132
145
|
/** Suspends a turn only for a Framework-owned lifecycle boundary. */
|
|
133
146
|
async yieldFrameworkPromise<T>(pending: Promise<T>): Promise<T> {
|
|
134
147
|
this.signalSuspended();
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
148
|
+
try {
|
|
149
|
+
return await pending;
|
|
150
|
+
} finally {
|
|
151
|
+
await this.awaitResumePermit();
|
|
152
|
+
}
|
|
138
153
|
}
|
|
139
154
|
|
|
140
155
|
async resumeOwnerUntilNextYield(): Promise<void> {
|
|
@@ -204,16 +219,18 @@ export function currentZLinkSpotSerialSourceId(): unknown {
|
|
|
204
219
|
|
|
205
220
|
export function requireZLinkYieldTurn(capturedTurn?: ZLinkSpotSerialTurn): ZLinkSpotSerialTurn {
|
|
206
221
|
const turn = capturedTurn ?? captureZLinkSpotSerialTurn();
|
|
207
|
-
if (turn === undefined
|
|
208
|
-
throw
|
|
209
|
-
|
|
222
|
+
if (turn === undefined) {
|
|
223
|
+
throw createInternalFrameworkException(
|
|
224
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
225
|
+
'Yield requires a current SpotWide application turn.'
|
|
210
226
|
);
|
|
211
227
|
}
|
|
228
|
+
turn.admitYield();
|
|
212
229
|
return turn;
|
|
213
230
|
}
|
|
214
231
|
|
|
215
232
|
export interface ZLinkCapturedExecutionTurn {
|
|
216
|
-
yieldPromise<T>(
|
|
233
|
+
yieldPromise<T>(operation: () => Promise<T>): Promise<T>;
|
|
217
234
|
post(callback: () => void): void;
|
|
218
235
|
}
|
|
219
236
|
|
|
@@ -223,7 +240,16 @@ export function captureZLinkExecutionTurn(): ZLinkCapturedExecutionTurn | undefi
|
|
|
223
240
|
return undefined;
|
|
224
241
|
}
|
|
225
242
|
return {
|
|
226
|
-
yieldPromise: <T>(
|
|
243
|
+
yieldPromise: <T>(operation: () => Promise<T>) => {
|
|
244
|
+
const turn = requireZLinkYieldTurn(current.turn);
|
|
245
|
+
let pending: Promise<T>;
|
|
246
|
+
try {
|
|
247
|
+
pending = operation();
|
|
248
|
+
} catch (error) {
|
|
249
|
+
pending = Promise.reject(error);
|
|
250
|
+
}
|
|
251
|
+
return turn.yieldFrameworkPromise(pending);
|
|
252
|
+
},
|
|
227
253
|
post: (callback: () => void) => {
|
|
228
254
|
void current.executor.post(callback);
|
|
229
255
|
}
|
|
@@ -241,7 +267,7 @@ export function isCurrentZLinkSpotSerialTurn(executor: ZLinkSpotSerialTurnExecut
|
|
|
241
267
|
|
|
242
268
|
export interface ZLinkExecutionBarrierSeal {
|
|
243
269
|
readonly generation: bigint;
|
|
244
|
-
readonly kind: 'close' | 'relocation';
|
|
270
|
+
readonly kind: 'close' | 'relocation' | 'activation';
|
|
245
271
|
}
|
|
246
272
|
|
|
247
273
|
export interface ZLinkExecutionBarrierClaim {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { macrotaskBoundary } from '../abort';
|
|
2
2
|
import {
|
|
3
3
|
diagnosticWorkName,
|
|
4
|
+
startOutsideStateLane,
|
|
4
5
|
guardStateLaneCompletion,
|
|
5
6
|
isStructuralGuardEnabled,
|
|
6
7
|
trackDiagnosticCompletion
|
|
@@ -9,6 +10,9 @@ import {
|
|
|
9
10
|
export type ZLinkSerialWorkLane = 'application' | 'lifecycle';
|
|
10
11
|
|
|
11
12
|
export interface ZLinkSerialWorkOptions {
|
|
13
|
+
readonly onAdmitted?: () => void;
|
|
14
|
+
/** Transfers an unstarted durable record out of this FIFO in the owner turn. */
|
|
15
|
+
readonly onWithdrawable?: (withdraw: () => boolean) => void;
|
|
12
16
|
readonly lane?: ZLinkSerialWorkLane;
|
|
13
17
|
readonly payloadBytes?: number;
|
|
14
18
|
readonly metadataBytes?: number;
|
|
@@ -166,12 +170,22 @@ export class ZLinkSerialExecutionQueue {
|
|
|
166
170
|
return this.admit(operation, { lane: 'lifecycle' }, context, undefined, true);
|
|
167
171
|
}
|
|
168
172
|
|
|
173
|
+
get retainsApplicationForLifecycle(): boolean {
|
|
174
|
+
return this.activeLifecycle?.context !== undefined;
|
|
175
|
+
}
|
|
176
|
+
|
|
169
177
|
visitPendingApplication(visitor: (record: ZLinkSerialWorkRecord<unknown>) => void): void {
|
|
170
178
|
for (const record of this.application.records) {
|
|
171
179
|
if (record.mailbox === undefined) visitor(record);
|
|
172
180
|
}
|
|
173
181
|
}
|
|
174
182
|
|
|
183
|
+
get hasPendingDurableApplication(): boolean {
|
|
184
|
+
// Every application record accepted behind durable work inherits durable
|
|
185
|
+
// ownership, so the tail answers this without scanning the FIFO.
|
|
186
|
+
return this.application.records.at(-1)?.preparation !== undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
175
189
|
get hasPendingWork(): boolean {
|
|
176
190
|
return (
|
|
177
191
|
this.consumer?.running === true ||
|
|
@@ -269,6 +283,19 @@ export class ZLinkSerialExecutionQueue {
|
|
|
269
283
|
release();
|
|
270
284
|
throw error;
|
|
271
285
|
}
|
|
286
|
+
options.onAdmitted?.();
|
|
287
|
+
options.onWithdrawable?.(() => {
|
|
288
|
+
const index = target.records.indexOf(record as SerialWorkRecord<unknown>);
|
|
289
|
+
if (index < 0) return false;
|
|
290
|
+
target.records.splice(index, 1);
|
|
291
|
+
record.preparationController?.abort(
|
|
292
|
+
new Error('Durable record transferred to another handoff.')
|
|
293
|
+
);
|
|
294
|
+
record.preparation?.cancel();
|
|
295
|
+
resolve(undefined as T);
|
|
296
|
+
release();
|
|
297
|
+
return true;
|
|
298
|
+
});
|
|
272
299
|
this.scheduleDrain();
|
|
273
300
|
return result;
|
|
274
301
|
}
|
|
@@ -284,10 +311,12 @@ export class ZLinkSerialExecutionQueue {
|
|
|
284
311
|
const consumer = this.consumer!;
|
|
285
312
|
if (consumer.scheduled || consumer.running) return;
|
|
286
313
|
consumer.scheduled = true;
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
314
|
+
startOutsideStateLane(() =>
|
|
315
|
+
queueMicrotask(() => {
|
|
316
|
+
consumer.scheduled = false;
|
|
317
|
+
void this.drain();
|
|
318
|
+
})
|
|
319
|
+
);
|
|
291
320
|
}
|
|
292
321
|
|
|
293
322
|
/** Notifications carry no payload, admission sequence, result Promise, or host permit. */
|
|
@@ -12,6 +12,13 @@ export function isStructuralGuardEnabled(): boolean {
|
|
|
12
12
|
return process.env.ZLINK_NODE_STRUCTURAL_GUARD === '1' || process.env.NODE_ENV === 'test';
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/** Detaches lane ownership while preserving the caller's other execution contexts. */
|
|
16
|
+
export function startOutsideStateLane<T>(work: () => T): T {
|
|
17
|
+
return currentLaneStorage.exit(() =>
|
|
18
|
+
diagnosticTurnStorage === undefined ? work() : diagnosticTurnStorage.exit(work)
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
15
22
|
const currentLaneStorage = new AsyncLocalStorage<ZLinkStateLane>();
|
|
16
23
|
const diagnosticPending = isStructuralGuardEnabled() ? new Map<number, string>() : undefined;
|
|
17
24
|
let nextDiagnosticWork = 0;
|
|
@@ -131,7 +131,7 @@ export function encodeCanonicalActorJoinRecoverySavedWork(
|
|
|
131
131
|
const replyContentType =
|
|
132
132
|
operationId === undefined
|
|
133
133
|
? null
|
|
134
|
-
:
|
|
134
|
+
: (nullableText(input.replyContentType ?? null, 'Actor Join reply content type') ?? null);
|
|
135
135
|
const metadata = encodeMetadataJson({
|
|
136
136
|
Request: {
|
|
137
137
|
ActorId: requireText(input.actorId, 'Actor id'),
|
|
@@ -288,7 +288,7 @@ export function decodeCanonicalActorJoinRecoverySavedWork(
|
|
|
288
288
|
const operationLow = integer(metadata.OperationIdLow, 'OperationIdLow');
|
|
289
289
|
const hasOperation = operationHigh !== 0n || operationLow !== 0n;
|
|
290
290
|
const replyContentType = nullableText(metadata.ReplyContentType, 'ReplyContentType');
|
|
291
|
-
if (hasOperation
|
|
291
|
+
if (!hasOperation && replyContentType !== undefined) {
|
|
292
292
|
throw new TypeError('Canonical Actor Join recovery reply identity is invalid.');
|
|
293
293
|
}
|
|
294
294
|
const targetNodeRid = base64(metadata.TargetNodeRid, 'TargetNodeRid');
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { awaitWithAbort } from '../abort';
|
|
2
|
+
import { RequestResult, SubmitResult, isZLinkBackendResultError } from '../backend/runtime-values';
|
|
3
|
+
import {
|
|
4
|
+
ZLinkFrameworkInternalErrorKind,
|
|
5
|
+
createInternalFrameworkException
|
|
6
|
+
} from '../framework-errors-internal';
|
|
7
|
+
|
|
8
|
+
export interface PeerRouteObservation {
|
|
9
|
+
readonly generation?: bigint;
|
|
10
|
+
readonly ready: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface DurableServiceRequestPort {
|
|
14
|
+
readonly requestStopSignal?: AbortSignal;
|
|
15
|
+
observePeerRoute(target: string): PeerRouteObservation;
|
|
16
|
+
observePeerRouteChanged(listener: (target: string) => void): () => void;
|
|
17
|
+
observePeerConnectionIntentRemoved(listener: (target: string) => void): () => void;
|
|
18
|
+
requestService(
|
|
19
|
+
target: string,
|
|
20
|
+
parts: readonly Uint8Array[],
|
|
21
|
+
timeoutMs: number,
|
|
22
|
+
onAdmitted?: () => void
|
|
23
|
+
): Promise<readonly Buffer[]>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Actor model §8.1: a ready edge or a typed transport failure owns replay. */
|
|
27
|
+
export async function requestDurableService(
|
|
28
|
+
port: DurableServiceRequestPort,
|
|
29
|
+
target: string,
|
|
30
|
+
parts: readonly Uint8Array[],
|
|
31
|
+
deadlineMs: number,
|
|
32
|
+
operationKind: string,
|
|
33
|
+
signal?: AbortSignal,
|
|
34
|
+
onSubmitted?: (signal: AbortSignal) => Promise<void>
|
|
35
|
+
): Promise<readonly Buffer[]> {
|
|
36
|
+
let wasAdmitted = false;
|
|
37
|
+
const stop = new AbortController();
|
|
38
|
+
const exhausted = (cause?: unknown) =>
|
|
39
|
+
createInternalFrameworkException(
|
|
40
|
+
wasAdmitted
|
|
41
|
+
? ZLinkFrameworkInternalErrorKind.DeadlineExceeded
|
|
42
|
+
: ZLinkFrameworkInternalErrorKind.RouteNotConnected,
|
|
43
|
+
`${operationKind} exhausted its end-to-end deadline.`,
|
|
44
|
+
true,
|
|
45
|
+
cause
|
|
46
|
+
);
|
|
47
|
+
const timer = setTimeout(
|
|
48
|
+
() => stop.abort(exhausted()),
|
|
49
|
+
Math.max(0, Math.ceil(deadlineMs - performance.now()))
|
|
50
|
+
);
|
|
51
|
+
const unobserveIntent = port.observePeerConnectionIntentRemoved((rid) => {
|
|
52
|
+
if (rid === target)
|
|
53
|
+
stop.abort(
|
|
54
|
+
createInternalFrameworkException(
|
|
55
|
+
ZLinkFrameworkInternalErrorKind.RouteNotConnected,
|
|
56
|
+
`${operationKind} target node lifecycle ended.`,
|
|
57
|
+
true
|
|
58
|
+
)
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
const cancellation = AbortSignal.any([
|
|
62
|
+
stop.signal,
|
|
63
|
+
...(signal === undefined ? [] : [signal]),
|
|
64
|
+
...(port.requestStopSignal === undefined ? [] : [port.requestStopSignal])
|
|
65
|
+
]);
|
|
66
|
+
try {
|
|
67
|
+
for (;;) {
|
|
68
|
+
cancellation.throwIfAborted();
|
|
69
|
+
const remainingMs = Math.ceil(deadlineMs - performance.now());
|
|
70
|
+
if (remainingMs <= 0) throw exhausted();
|
|
71
|
+
let changed!: () => void;
|
|
72
|
+
const transition = new Promise<void>((resolve) => {
|
|
73
|
+
changed = resolve;
|
|
74
|
+
});
|
|
75
|
+
let submittedGeneration: bigint | undefined;
|
|
76
|
+
const attemptStop = new AbortController();
|
|
77
|
+
const attemptSignal = AbortSignal.any([cancellation, attemptStop.signal]);
|
|
78
|
+
const unobserveRoute = port.observePeerRouteChanged((rid) => {
|
|
79
|
+
if (rid !== target) return;
|
|
80
|
+
const route = port.observePeerRoute(target);
|
|
81
|
+
if (
|
|
82
|
+
submittedGeneration === undefined
|
|
83
|
+
? route.ready
|
|
84
|
+
: route.generation !== undefined && route.generation !== submittedGeneration
|
|
85
|
+
) {
|
|
86
|
+
changed();
|
|
87
|
+
attemptStop.abort();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
try {
|
|
91
|
+
const route = port.observePeerRoute(target);
|
|
92
|
+
if (!route.ready) {
|
|
93
|
+
await awaitWithAbort(transition, cancellation);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
submittedGeneration = route.generation;
|
|
97
|
+
const reply = port.requestService(target, parts, remainingMs, () => {
|
|
98
|
+
wasAdmitted = true;
|
|
99
|
+
});
|
|
100
|
+
const request =
|
|
101
|
+
onSubmitted === undefined
|
|
102
|
+
? reply
|
|
103
|
+
: Promise.race([
|
|
104
|
+
reply,
|
|
105
|
+
Promise.resolve()
|
|
106
|
+
.then(() => onSubmitted(attemptSignal))
|
|
107
|
+
.then(() => reply)
|
|
108
|
+
]);
|
|
109
|
+
const result = await awaitWithAbort(
|
|
110
|
+
Promise.race([request.then((parts) => ({ parts })), transition.then(() => undefined)]),
|
|
111
|
+
cancellation
|
|
112
|
+
);
|
|
113
|
+
if (result !== undefined) return result.parts;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
cancellation.throwIfAborted();
|
|
116
|
+
if (!durableRequestCanReplay(error)) throw error;
|
|
117
|
+
if (isZLinkBackendResultError(error) && error.operation === 'request') wasAdmitted = true;
|
|
118
|
+
} finally {
|
|
119
|
+
attemptStop.abort();
|
|
120
|
+
unobserveRoute();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} finally {
|
|
124
|
+
clearTimeout(timer);
|
|
125
|
+
unobserveIntent();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function durableRequestCanReplay(error: unknown): boolean {
|
|
130
|
+
if (!isZLinkBackendResultError(error)) return false;
|
|
131
|
+
return error.operation === 'request'
|
|
132
|
+
? error.result === RequestResult.NotConnected || error.result === RequestResult.TimedOut
|
|
133
|
+
: error.result === SubmitResult.NotConnected ||
|
|
134
|
+
error.result === SubmitResult.NotFound ||
|
|
135
|
+
error.result === SubmitResult.NotAdmitted ||
|
|
136
|
+
error.result === SubmitResult.Backpressured;
|
|
137
|
+
}
|
|
@@ -19,12 +19,16 @@ export type ZLinkOperationIdentityKey = string & {
|
|
|
19
19
|
export function operationIdentityKey(
|
|
20
20
|
operationId: ZLinkOperationIdentity128
|
|
21
21
|
): ZLinkOperationIdentityKey {
|
|
22
|
+
validateOperationIdentity(operationId);
|
|
23
|
+
return `${operationId.high.toString(16)}:${operationId.low.toString(16)}` as ZLinkOperationIdentityKey;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function validateOperationIdentity(operationId: ZLinkOperationIdentity128): void {
|
|
22
27
|
requireUnsigned64(operationId.high, 'operationId.high');
|
|
23
28
|
requireUnsigned64(operationId.low, 'operationId.low');
|
|
24
29
|
if (operationId.high === 0n && operationId.low === 0n) {
|
|
25
30
|
throw new RangeError('Operation identity must not be all zero.');
|
|
26
31
|
}
|
|
27
|
-
return `${operationId.high.toString(16)}:${operationId.low.toString(16)}` as ZLinkOperationIdentityKey;
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
export function createRandomOperationIdentity(
|
|
@@ -24,11 +24,22 @@ export interface PendingOperation<T> {
|
|
|
24
24
|
readonly promise: Promise<T>;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Receives an operation's terminal at the place it is taken from the
|
|
29
|
+
* registry. One long-lived observer serves every observed operation, so an
|
|
30
|
+
* observed registration creates no Promise or per-operation callback.
|
|
31
|
+
*/
|
|
32
|
+
export interface OperationObserver<T, Context> {
|
|
33
|
+
operationCompleted(id: bigint, value: T, context: Context | undefined): void;
|
|
34
|
+
operationFailed(id: bigint, reason: unknown, context: Context | undefined): void;
|
|
35
|
+
}
|
|
36
|
+
|
|
27
37
|
interface Entry<T, Context> {
|
|
28
38
|
readonly context: Context | undefined;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
deadlineMs?: number;
|
|
40
|
+
resolve?: (value: T | PromiseLike<T>) => void;
|
|
41
|
+
reject?: (reason: unknown) => void;
|
|
42
|
+
observer?: OperationObserver<T, Context>;
|
|
32
43
|
}
|
|
33
44
|
|
|
34
45
|
const systemClock: OperationClock = {
|
|
@@ -40,7 +51,14 @@ export class OperationRegistry<T, Context = unknown> {
|
|
|
40
51
|
private readonly entries = new Map<bigint, Entry<T, Context>>();
|
|
41
52
|
private nextId = 1n;
|
|
42
53
|
private deadlineCursor?: MapIterator<[bigint, Entry<T, Context>]>;
|
|
54
|
+
/**
|
|
55
|
+
* A lower bound of the earliest pending deadline. Completed entries only
|
|
56
|
+
* leave it early; a full expiry pass replaces it with the exact value.
|
|
57
|
+
*/
|
|
58
|
+
private earliestDeadlineMs = Number.POSITIVE_INFINITY;
|
|
59
|
+
private scanEarliestDeadlineMs = Number.POSITIVE_INFINITY;
|
|
43
60
|
private closed = false;
|
|
61
|
+
private pendingCount = 0;
|
|
44
62
|
|
|
45
63
|
constructor(
|
|
46
64
|
private readonly clock: OperationClock = systemClock,
|
|
@@ -63,28 +81,56 @@ export class OperationRegistry<T, Context = unknown> {
|
|
|
63
81
|
resolve = onResolve;
|
|
64
82
|
reject = onReject;
|
|
65
83
|
});
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
deadlineMs: timeoutOwner === 'registry' ? this.clock.now() + timeoutMs : undefined,
|
|
69
|
-
resolve,
|
|
70
|
-
reject
|
|
71
|
-
};
|
|
84
|
+
const deadlineMs = timeoutOwner === 'registry' ? this.clock.now() + timeoutMs : undefined;
|
|
85
|
+
const entry: Entry<T, Context> = { context, deadlineMs, resolve, reject };
|
|
72
86
|
this.entries.set(id, entry);
|
|
73
|
-
|
|
87
|
+
this.notePending(deadlineMs);
|
|
74
88
|
return { id, promise };
|
|
75
89
|
}
|
|
76
90
|
|
|
77
|
-
|
|
91
|
+
/** Registers an operation whose terminal goes to `observer` instead of a Promise. */
|
|
92
|
+
registerObserved(
|
|
93
|
+
timeoutMs: number,
|
|
94
|
+
observer: OperationObserver<T, Context>,
|
|
95
|
+
context?: Context
|
|
96
|
+
): bigint {
|
|
97
|
+
if (this.closed) throw new Error('Operation registry is closed.');
|
|
98
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
99
|
+
throw new RangeError('timeoutMs must be a non-negative finite number.');
|
|
100
|
+
}
|
|
101
|
+
const id = this.nextId++;
|
|
102
|
+
const deadlineMs = this.clock.now() + timeoutMs;
|
|
103
|
+
this.entries.set(id, { context, deadlineMs, observer });
|
|
104
|
+
this.notePending(deadlineMs);
|
|
105
|
+
return id;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** The time the next expiry pass has work, as a lower bound (spec 08 §4.2). */
|
|
109
|
+
nextDeadlineMs(): number {
|
|
110
|
+
return this.earliestDeadlineMs;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private notePending(deadlineMs: number | undefined): void {
|
|
114
|
+
this.pendingCount++;
|
|
115
|
+
const earlier = deadlineMs !== undefined && deadlineMs < this.earliestDeadlineMs;
|
|
116
|
+
if (earlier) this.earliestDeadlineMs = deadlineMs;
|
|
117
|
+
if (earlier || this.pendingCount === 1) this.onPendingChanged?.();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
complete(id: bigint, value: T, terminalContextRetentionMs = 0): boolean {
|
|
78
121
|
const entry = this.take(id);
|
|
79
122
|
if (entry === undefined) return false;
|
|
80
|
-
entry.
|
|
123
|
+
if (entry.observer !== undefined) entry.observer.operationCompleted(id, value, entry.context);
|
|
124
|
+
else entry.resolve!(value);
|
|
125
|
+
this.retainTerminal(id, entry, terminalContextRetentionMs);
|
|
81
126
|
return true;
|
|
82
127
|
}
|
|
83
128
|
|
|
84
129
|
fail(id: bigint, reason: unknown): boolean {
|
|
85
130
|
const entry = this.take(id);
|
|
86
131
|
if (entry === undefined) return false;
|
|
87
|
-
entry.
|
|
132
|
+
if (entry.observer !== undefined) entry.observer.operationFailed(id, reason, entry.context);
|
|
133
|
+
else entry.reject!(reason);
|
|
88
134
|
return true;
|
|
89
135
|
}
|
|
90
136
|
|
|
@@ -93,7 +139,7 @@ export class OperationRegistry<T, Context = unknown> {
|
|
|
93
139
|
}
|
|
94
140
|
|
|
95
141
|
isPending(id: bigint): boolean {
|
|
96
|
-
return this.
|
|
142
|
+
return this.pendingEntry(id) !== undefined;
|
|
97
143
|
}
|
|
98
144
|
|
|
99
145
|
context(id: bigint): Context | undefined {
|
|
@@ -104,35 +150,67 @@ export class OperationRegistry<T, Context = unknown> {
|
|
|
104
150
|
if (this.closed) return;
|
|
105
151
|
this.closed = true;
|
|
106
152
|
for (const id of this.entries.keys()) this.cancel(id, reason);
|
|
153
|
+
this.entries.clear();
|
|
107
154
|
this.deadlineCursor = undefined;
|
|
108
155
|
}
|
|
109
156
|
|
|
157
|
+
failAll(reason: unknown): void {
|
|
158
|
+
for (const id of this.entries.keys()) this.fail(id, reason);
|
|
159
|
+
}
|
|
160
|
+
|
|
110
161
|
get size(): number {
|
|
111
|
-
return this.
|
|
162
|
+
return this.pendingCount;
|
|
112
163
|
}
|
|
113
164
|
|
|
114
165
|
expire(nowMs: number, turnDeadlineMs: number): number {
|
|
115
166
|
let expired = 0;
|
|
116
167
|
while (this.clock.now() < turnDeadlineMs) {
|
|
117
|
-
this.deadlineCursor
|
|
168
|
+
if (this.deadlineCursor === undefined) {
|
|
169
|
+
this.deadlineCursor = this.entries.entries();
|
|
170
|
+
this.scanEarliestDeadlineMs = Number.POSITIVE_INFINITY;
|
|
171
|
+
}
|
|
118
172
|
const current = this.deadlineCursor.next();
|
|
119
173
|
if (current.done === true) {
|
|
120
174
|
this.deadlineCursor = undefined;
|
|
175
|
+
// Entries registered during the pass are appended and were scanned.
|
|
176
|
+
this.earliestDeadlineMs = this.scanEarliestDeadlineMs;
|
|
121
177
|
break;
|
|
122
178
|
}
|
|
123
179
|
const [id, entry] = current.value;
|
|
124
|
-
if (entry.deadlineMs
|
|
125
|
-
|
|
180
|
+
if (entry.deadlineMs === undefined) continue;
|
|
181
|
+
if (entry.deadlineMs <= nowMs) {
|
|
182
|
+
if (!this.isPending(id)) this.entries.delete(id);
|
|
183
|
+
else if (this.fail(id, new OperationTimeoutError(id))) expired++;
|
|
184
|
+
} else if (entry.deadlineMs < this.scanEarliestDeadlineMs) {
|
|
185
|
+
this.scanEarliestDeadlineMs = entry.deadlineMs;
|
|
126
186
|
}
|
|
127
187
|
}
|
|
128
188
|
return expired;
|
|
129
189
|
}
|
|
130
190
|
|
|
131
191
|
private take(id: bigint): Entry<T, Context> | undefined {
|
|
132
|
-
const entry = this.
|
|
192
|
+
const entry = this.pendingEntry(id);
|
|
133
193
|
if (entry === undefined) return undefined;
|
|
134
194
|
this.entries.delete(id);
|
|
135
|
-
|
|
195
|
+
this.pendingCount--;
|
|
196
|
+
if (this.pendingCount === 0) this.onPendingChanged?.();
|
|
136
197
|
return entry;
|
|
137
198
|
}
|
|
199
|
+
|
|
200
|
+
private pendingEntry(id: bigint): Entry<T, Context> | undefined {
|
|
201
|
+
const entry = this.entries.get(id);
|
|
202
|
+
return entry !== undefined && (entry.resolve !== undefined || entry.observer !== undefined)
|
|
203
|
+
? entry
|
|
204
|
+
: undefined;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private retainTerminal(id: bigint, entry: Entry<T, Context>, retentionMs: number): void {
|
|
208
|
+
if (this.closed || entry.context === undefined || retentionMs === 0) return;
|
|
209
|
+
entry.resolve = undefined;
|
|
210
|
+
entry.reject = undefined;
|
|
211
|
+
entry.observer = undefined;
|
|
212
|
+
entry.deadlineMs = this.clock.now() + retentionMs;
|
|
213
|
+
this.entries.set(id, entry);
|
|
214
|
+
this.earliestDeadlineMs = Math.min(this.earliestDeadlineMs, entry.deadlineMs);
|
|
215
|
+
}
|
|
138
216
|
}
|