@zlink-systems/framework 0.30.1 → 0.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
- package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
- package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
- package/dist/contracts/Common/encoded-payload-storage.js +5 -2
- package/dist/contracts/Configuration/Builders.d.ts +1 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
- package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
- package/dist/contracts/Locations/Rows.d.ts +2 -0
- package/dist/contracts/Spots/Contracts.d.ts +4 -0
- package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
- package/dist/runtime/abort.d.ts +5 -0
- package/dist/runtime/abort.js +10 -0
- package/dist/runtime/actors/actor-authority-publication.js +3 -2
- package/dist/runtime/actors/actor-client.d.ts +0 -1
- package/dist/runtime/actors/actor-client.js +38 -45
- package/dist/runtime/actors/actor-context.d.ts +2 -0
- package/dist/runtime/actors/actor-context.js +46 -9
- package/dist/runtime/actors/actor-handoff.d.ts +7 -3
- package/dist/runtime/actors/actor-handoff.js +212 -88
- package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
- package/dist/runtime/actors/actor-local-native-join.js +4 -0
- package/dist/runtime/actors/actor-mailbox.js +27 -1
- package/dist/runtime/actors/actor-remote-joiner.js +3 -1
- package/dist/runtime/actors/actor-reply.d.ts +4 -0
- package/dist/runtime/actors/actor-reply.js +29 -0
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
- package/dist/runtime/actors/actor-runtime-state.js +2 -20
- package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
- package/dist/runtime/actors/index.d.ts +6 -2
- package/dist/runtime/actors/index.js +37 -21
- package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
- package/dist/runtime/actors/session-disconnected-wire.js +48 -0
- package/dist/runtime/admission.d.ts +9 -1
- package/dist/runtime/admission.js +55 -32
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
- package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
- package/dist/runtime/application-jobs/contracts.d.ts +2 -0
- package/dist/runtime/backend/contracts/index.d.ts +19 -3
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
- package/dist/runtime/backend/mesh-completion-table.js +5 -0
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
- package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
- package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
- package/dist/runtime/channels/channel-clients.d.ts +1 -0
- package/dist/runtime/channels/channel-clients.js +20 -5
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
- package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
- package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
- package/dist/runtime/channels/channel-dispatchers.js +44 -37
- package/dist/runtime/channels/channel-envelope.d.ts +1 -0
- package/dist/runtime/channels/channel-envelope.js +74 -31
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
- package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
- package/dist/runtime/channels/channel-runtime-manager.js +4 -4
- package/dist/runtime/channels/channel-transports.d.ts +0 -1
- package/dist/runtime/channels/channel-transports.js +35 -33
- package/dist/runtime/channels/client-server-location-runtime.js +5 -4
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/fanout-location-runtime.js +3 -3
- package/dist/runtime/diagnostics/flow-context.js +19 -7
- package/dist/runtime/diagnostics/index.js +4 -9
- package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
- package/dist/runtime/diagnostics/message-flow.js +35 -5
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
- package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
- package/dist/runtime/execution/index.d.ts +4 -2
- package/dist/runtime/execution/index.js +33 -10
- package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
- package/dist/runtime/execution/serial-execution-queue.js +21 -2
- package/dist/runtime/execution/state-lane.d.ts +2 -0
- package/dist/runtime/execution/state-lane.js +5 -0
- package/dist/runtime/foundation/operation-registry.d.ts +25 -1
- package/dist/runtime/foundation/operation-registry.js +86 -18
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
- package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
- package/dist/runtime/foundation/service-liveness-registry.js +38 -0
- package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
- package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
- package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
- package/dist/runtime/foundation/service-stateful-registry.js +24 -26
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
- package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
- package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
- package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
- package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
- package/dist/runtime/host/actor-packet-relay.js +59 -72
- package/dist/runtime/host/actor-placement-coordinator.js +25 -8
- package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
- package/dist/runtime/host/actor-transfer-runtime.js +85 -331
- package/dist/runtime/host/application-job-queue.d.ts +24 -3
- package/dist/runtime/host/application-job-queue.js +28 -41
- package/dist/runtime/host/index.d.ts +5 -1
- package/dist/runtime/host/index.js +171 -97
- package/dist/runtime/host/location-runtime-owner.js +2 -6
- package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
- package/dist/runtime/host/mesh-router-resolver.js +14 -6
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
- package/dist/runtime/host/remote-bound-session-relay.js +71 -190
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
- package/dist/runtime/host/route-mesh-runtime.js +5 -3
- package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
- package/dist/runtime/host/runtime-shutdown.js +3 -2
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
- package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
- package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
- package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
- package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
- package/dist/runtime/locations/auto-connect-loop.js +22 -14
- package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
- package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
- package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
- package/dist/runtime/locations/descriptor-publication.js +11 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
- package/dist/runtime/locations/in-memory-authority-store.js +56 -19
- package/dist/runtime/locations/in-memory-location-store.js +1 -10
- package/dist/runtime/locations/index.d.ts +1 -0
- package/dist/runtime/locations/index.js +1 -0
- package/dist/runtime/locations/lease-tracker.js +1 -6
- package/dist/runtime/locations/location-store-repository.d.ts +51 -1
- package/dist/runtime/locations/location-store-repository.js +363 -139
- package/dist/runtime/locations/relocation-blob.d.ts +18 -1
- package/dist/runtime/locations/relocation-blob.js +52 -1
- package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
- package/dist/runtime/locations/request-source-resolver.js +80 -0
- package/dist/runtime/locations/resolvers.js +1 -1
- package/dist/runtime/locations/runtime.d.ts +6 -2
- package/dist/runtime/locations/runtime.js +37 -30
- package/dist/runtime/messaging/payload-codec.d.ts +7 -1
- package/dist/runtime/messaging/payload-codec.js +7 -6
- package/dist/runtime/messaging/request-result.js +29 -26
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
- package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
- package/dist/runtime/spots/index.d.ts +18 -11
- package/dist/runtime/spots/index.js +234 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +21 -11
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +7 -7
- package/dist/runtime/spots/spot-activation.d.ts +6 -3
- package/dist/runtime/spots/spot-activation.js +123 -44
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
- package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-membership.js +0 -8
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
- package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
- package/dist/runtime/spots/spot-entry-activation.js +14 -9
- package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
- package/dist/runtime/spots/spot-handler-registry.js +6 -2
- package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
- package/dist/runtime/spots/spot-manager-public.js +2 -2
- package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
- package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
- package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
- package/dist/runtime/spots/spot-outbound.js +3 -3
- package/dist/runtime/spots/spot-remote-codec.js +5 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
- package/dist/runtime/spots/spot-serial-executor.js +61 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
- package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
- package/dist/runtime/spots/spot-timer.d.ts +57 -5
- package/dist/runtime/spots/spot-timer.js +287 -103
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
- package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
- package/dist/runtime/streams/bound-session-service.d.ts +1 -1
- package/dist/runtime/streams/bound-session-service.js +6 -11
- package/dist/runtime/streams/index.d.ts +3 -2
- package/dist/runtime/streams/index.js +6 -4
- package/dist/runtime/streams/managed-stream.js +3 -2
- package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
- package/dist/runtime/streams/session-actor-coordinator.js +15 -32
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
- package/dist/runtime/streams/stream-session-runtime.js +1 -4
- package/dist/runtime/workers/index.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
- package/src/contracts/Common/encoded-payload-storage.ts +6 -3
- package/src/contracts/Configuration/Builders.ts +4 -1
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
- package/src/contracts/Locations/Rows.ts +2 -0
- package/src/contracts/Spots/Contracts.ts +8 -0
- package/src/contracts/Spots/ZLinkSpot.ts +3 -3
- package/src/runtime/abort.ts +12 -0
- package/src/runtime/actors/actor-authority-publication.ts +3 -2
- package/src/runtime/actors/actor-client.ts +61 -70
- package/src/runtime/actors/actor-context.ts +49 -9
- package/src/runtime/actors/actor-handoff.ts +282 -106
- package/src/runtime/actors/actor-join-relocation.ts +2 -0
- package/src/runtime/actors/actor-local-native-join.ts +4 -0
- package/src/runtime/actors/actor-mailbox.ts +40 -2
- package/src/runtime/actors/actor-remote-joiner.ts +6 -1
- package/src/runtime/actors/actor-reply.ts +42 -0
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
- package/src/runtime/actors/actor-runtime-state.ts +2 -20
- package/src/runtime/actors/actor-source-transfer.ts +1 -34
- package/src/runtime/actors/index.ts +41 -27
- package/src/runtime/actors/session-disconnected-wire.ts +66 -0
- package/src/runtime/admission.ts +69 -34
- package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
- package/src/runtime/application-jobs/contracts.ts +2 -0
- package/src/runtime/backend/contracts/index.ts +39 -4
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
- package/src/runtime/backend/mesh-completion-table.ts +4 -0
- package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
- package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
- package/src/runtime/channels/channel-clients.ts +49 -24
- package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
- package/src/runtime/channels/channel-dispatchers.ts +116 -72
- package/src/runtime/channels/channel-envelope.ts +105 -36
- package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
- package/src/runtime/channels/channel-runtime-manager.ts +12 -5
- package/src/runtime/channels/channel-transports.ts +49 -58
- package/src/runtime/channels/client-server-location-runtime.ts +11 -10
- package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
- package/src/runtime/channels/fanout-location-runtime.ts +17 -9
- package/src/runtime/diagnostics/flow-context.ts +20 -7
- package/src/runtime/diagnostics/index.ts +1 -7
- package/src/runtime/diagnostics/message-flow.ts +47 -9
- package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
- package/src/runtime/execution/index.ts +40 -14
- package/src/runtime/execution/serial-execution-queue.ts +31 -4
- package/src/runtime/execution/state-lane.ts +7 -0
- package/src/runtime/foundation/operation-registry.ts +98 -20
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
- package/src/runtime/foundation/service-liveness-registry.ts +39 -0
- package/src/runtime/foundation/service-mailbox.ts +8 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
- package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
- package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
- package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
- package/src/runtime/foundation/service-stateful-registry.ts +38 -35
- package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
- package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
- package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
- package/src/runtime/host/actor-packet-relay.ts +113 -94
- package/src/runtime/host/actor-placement-coordinator.ts +31 -8
- package/src/runtime/host/actor-transfer-runtime.ts +104 -430
- package/src/runtime/host/application-job-queue.ts +29 -44
- package/src/runtime/host/index.ts +286 -129
- package/src/runtime/host/location-runtime-owner.ts +2 -6
- package/src/runtime/host/mesh-router-resolver.ts +13 -5
- package/src/runtime/host/remote-bound-session-relay.ts +86 -248
- package/src/runtime/host/route-mesh-runtime.ts +11 -5
- package/src/runtime/host/runtime-shutdown.ts +15 -4
- package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
- package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
- package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
- package/src/runtime/locations/auto-connect-loop.ts +22 -14
- package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
- package/src/runtime/locations/auto-connect-types.ts +0 -1
- package/src/runtime/locations/descriptor-publication.ts +7 -0
- package/src/runtime/locations/domain-store-contract.ts +5 -0
- package/src/runtime/locations/in-memory-authority-store.ts +85 -23
- package/src/runtime/locations/in-memory-location-store.ts +1 -12
- package/src/runtime/locations/index.ts +1 -0
- package/src/runtime/locations/lease-tracker.ts +2 -9
- package/src/runtime/locations/location-store-repository.ts +628 -152
- package/src/runtime/locations/relocation-blob.ts +75 -1
- package/src/runtime/locations/request-source-resolver.ts +138 -0
- package/src/runtime/locations/resolvers.ts +2 -2
- package/src/runtime/locations/runtime.ts +70 -40
- package/src/runtime/messaging/payload-codec.ts +8 -11
- package/src/runtime/messaging/request-result.ts +33 -29
- package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
- package/src/runtime/spots/index.ts +375 -281
- package/src/runtime/spots/spot-activation-registry.ts +25 -13
- package/src/runtime/spots/spot-activation-state.ts +12 -19
- package/src/runtime/spots/spot-activation.ts +170 -86
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
- package/src/runtime/spots/spot-actor-membership.ts +0 -15
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
- package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
- package/src/runtime/spots/spot-entry-activation.ts +24 -19
- package/src/runtime/spots/spot-handler-registry.ts +15 -4
- package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
- package/src/runtime/spots/spot-manager-public.ts +2 -2
- package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
- package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
- package/src/runtime/spots/spot-outbound.ts +3 -3
- package/src/runtime/spots/spot-remote-codec.ts +9 -2
- package/src/runtime/spots/spot-runtime-ports.ts +0 -1
- package/src/runtime/spots/spot-serial-executor.ts +97 -25
- package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
- package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
- package/src/runtime/spots/spot-timer.ts +413 -157
- package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
- package/src/runtime/streams/bound-session-service.ts +7 -10
- package/src/runtime/streams/index.ts +12 -6
- package/src/runtime/streams/managed-stream.ts +4 -2
- package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
- package/src/runtime/streams/session-actor-coordinator.ts +39 -88
- package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
- package/src/runtime/streams/stream-session-runtime.ts +1 -5
- package/src/runtime/workers/index.ts +1 -1
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ZLinkActorHandoffCoordinator = exports.DEFAULT_MESSAGE_FOLLOW_DURATION_MS = void 0;
|
|
3
|
+
exports.ZLinkActorHandoffCoordinator = exports.RELOCATED_REQUEST_OWNED_BY_REQUESTER = exports.DEFAULT_MESSAGE_FOLLOW_DURATION_MS = void 0;
|
|
4
4
|
exports.decodeHandoffPacket = decodeHandoffPacket;
|
|
5
5
|
exports.replayActorHandoffBacklog = replayActorHandoffBacklog;
|
|
6
6
|
const contracts_1 = require("../../contracts");
|
|
7
|
+
const Registration_1 = require("../../contracts/Configuration/Registration");
|
|
7
8
|
const Options_1 = require("../../contracts/Locations/Options");
|
|
8
9
|
const application_job_queue_scope_1 = require("../application-jobs/application-job-queue-scope");
|
|
9
10
|
const runtime_message_1 = require("../backend/runtime-message");
|
|
10
11
|
const message_follow_suppression_registry_1 = require("../foundation/message-follow-suppression-registry");
|
|
12
|
+
const service_stateful_registry_1 = require("../foundation/service-stateful-registry");
|
|
13
|
+
const operation_identity_1 = require("../foundation/operation-identity");
|
|
14
|
+
const stream_wire_1 = require("@zlink-systems/stream-wire");
|
|
11
15
|
const framework_errors_internal_1 = require("../framework-errors-internal");
|
|
16
|
+
const request_deadline_1 = require("../messaging/request-deadline");
|
|
12
17
|
const routing_id_1 = require("../routing-id");
|
|
13
18
|
const protocol_1 = require("../streams/protocol");
|
|
14
19
|
const actor_message_follow_context_1 = require("./actor-message-follow-context");
|
|
15
20
|
const actor_packet_relay_wire_1 = require("./actor-packet-relay-wire");
|
|
16
21
|
const actor_routed_json_request_1 = require("./actor-routed-json-request");
|
|
17
22
|
exports.DEFAULT_MESSAGE_FOLLOW_DURATION_MS = Options_1.zlinkDefaultLocationOptions.messageFollowDurationMs;
|
|
18
|
-
|
|
23
|
+
exports.RELOCATED_REQUEST_OWNED_BY_REQUESTER = Symbol('relocated request owned by requester');
|
|
19
24
|
function requireExactTargetOwnerFence(actorId, fence) {
|
|
20
25
|
if (fence === undefined) {
|
|
21
26
|
throw new Error(`Actor '${actorId}' handoff requires a committed target owner fence.`);
|
|
@@ -31,6 +36,8 @@ function requireExactTargetOwnerFence(actorId, fence) {
|
|
|
31
36
|
class ZLinkActorHandoffCoordinator {
|
|
32
37
|
options;
|
|
33
38
|
active = new Map();
|
|
39
|
+
// Each route is stored once: Actor -> native fence -> location owner id.
|
|
40
|
+
// Native ingress has the complete fence except the location owner's text id.
|
|
34
41
|
messageFollowRoutes = new Map();
|
|
35
42
|
messageFollowSuppression = new message_follow_suppression_registry_1.MessageFollowSuppressionRegistry();
|
|
36
43
|
// Relocation preserves ObjectGeneration, so (nodeRid, objectGeneration) alone
|
|
@@ -56,7 +63,10 @@ class ZLinkActorHandoffCoordinator {
|
|
|
56
63
|
this.startHandoff(actorId, oldGeneration, 'provisional');
|
|
57
64
|
}
|
|
58
65
|
startHandoff(actorId, oldGeneration, phase) {
|
|
59
|
-
|
|
66
|
+
// A releasing handoff has returned its hold to the Actor FIFO; only its
|
|
67
|
+
// durable prefix drain remains, and the next hold takes over its ingress.
|
|
68
|
+
const previous = this.active.get(actorId);
|
|
69
|
+
if (this.isActive(actorId)) {
|
|
60
70
|
throw new Error(`Actor '${actorId}' already has an active packet handoff.`);
|
|
61
71
|
}
|
|
62
72
|
if (oldGeneration <= 0n) {
|
|
@@ -92,6 +102,25 @@ class ZLinkActorHandoffCoordinator {
|
|
|
92
102
|
nodeGeneration: source.nodeGeneration,
|
|
93
103
|
authorityOwnerGeneration: source.authorityOwnerGeneration
|
|
94
104
|
});
|
|
105
|
+
const pending = [];
|
|
106
|
+
if (previous?.prefixRelease !== undefined) {
|
|
107
|
+
// Only records still in the FIFO belong to the new barrier. Running
|
|
108
|
+
// records keep their existing terminal; withdrawn records surrender
|
|
109
|
+
// readiness and move their payload before later ingress can arrive.
|
|
110
|
+
for (let index = 0; index < previous.pending.length;) {
|
|
111
|
+
const record = previous.pending[index];
|
|
112
|
+
if (record.withdraw?.() === true) {
|
|
113
|
+
record.withdraw = undefined;
|
|
114
|
+
pending.push(record);
|
|
115
|
+
previous.pending.splice(index, 1);
|
|
116
|
+
previous.prefixRelease.cursor -= 1;
|
|
117
|
+
previous.pendingBytes -= packetBytes(record.packet);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
index += 1;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
95
124
|
this.active.set(actorId, {
|
|
96
125
|
oldGeneration,
|
|
97
126
|
oldNodeRid: sourceOwner.nodeRid,
|
|
@@ -101,25 +130,20 @@ class ZLinkActorHandoffCoordinator {
|
|
|
101
130
|
phase,
|
|
102
131
|
deferredJoin: phase === 'provisional',
|
|
103
132
|
connectionBoundSealed: false,
|
|
104
|
-
pending
|
|
105
|
-
nextIndex: 0,
|
|
133
|
+
pending,
|
|
134
|
+
nextIndex: pending.reduce((next, record) => Math.max(next, record.packet.index + 1), 0),
|
|
106
135
|
snapshotIndex: -1,
|
|
107
|
-
pendingBytes: 0
|
|
136
|
+
pendingBytes: pending.reduce((bytes, record) => bytes + packetBytes(record.packet), 0)
|
|
108
137
|
});
|
|
109
138
|
}
|
|
139
|
+
/** True while a hold owns this Actor's ingress, before its release to the Actor FIFO. */
|
|
110
140
|
isActive(actorId) {
|
|
111
|
-
|
|
141
|
+
const handoff = this.active.get(actorId);
|
|
142
|
+
return handoff !== undefined && handoff.phase !== 'releasing';
|
|
112
143
|
}
|
|
113
144
|
isProvisional(actorId) {
|
|
114
145
|
return this.active.get(actorId)?.phase === 'provisional';
|
|
115
146
|
}
|
|
116
|
-
promoteProvisional(actorId) {
|
|
117
|
-
const handoff = this.active.get(actorId);
|
|
118
|
-
if (handoff?.phase !== 'provisional') {
|
|
119
|
-
throw new Error(`Actor '${actorId}' does not have a provisional packet handoff.`);
|
|
120
|
-
}
|
|
121
|
-
handoff.phase = 'relocating';
|
|
122
|
-
}
|
|
123
147
|
sealConnectionBoundIngress(actorId) {
|
|
124
148
|
const handoff = this.active.get(actorId);
|
|
125
149
|
if (handoff !== undefined)
|
|
@@ -166,6 +190,33 @@ class ZLinkActorHandoffCoordinator {
|
|
|
166
190
|
return { terminal: Promise.resolve() };
|
|
167
191
|
return this.admitHandoffPrefix(actorId, handoff, queue, preparation, start);
|
|
168
192
|
}
|
|
193
|
+
/** Installs a restored target's payload in the same owner used by local handoffs. */
|
|
194
|
+
admitTransferredPrefix(actorId, objectGeneration, packets, queue, preparation, start, onResult) {
|
|
195
|
+
this.beginProvisional(actorId, objectGeneration);
|
|
196
|
+
const handoff = this.requireActive(actorId);
|
|
197
|
+
for (const packet of packets) {
|
|
198
|
+
handoff.pending.push({
|
|
199
|
+
packet,
|
|
200
|
+
origin: 'remote',
|
|
201
|
+
resolve: (response) => {
|
|
202
|
+
if (response !== exports.RELOCATED_REQUEST_OWNED_BY_REQUESTER) {
|
|
203
|
+
onResult(packet, { index: packet.index, ok: true, response });
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
reject: (error) => onResult(packet, {
|
|
207
|
+
index: packet.index,
|
|
208
|
+
ok: false,
|
|
209
|
+
error: error instanceof Error ? error.message : String(error),
|
|
210
|
+
errorKind: error instanceof contracts_1.ZLinkFrameworkException
|
|
211
|
+
? (0, framework_errors_internal_1.internalFrameworkErrorKind)(error)
|
|
212
|
+
: undefined
|
|
213
|
+
})
|
|
214
|
+
});
|
|
215
|
+
handoff.nextIndex = Math.max(handoff.nextIndex, packet.index + 1);
|
|
216
|
+
handoff.pendingBytes += packetBytes(packet);
|
|
217
|
+
}
|
|
218
|
+
return this.admitHandoffPrefix(actorId, handoff, queue, preparation, start);
|
|
219
|
+
}
|
|
169
220
|
admitHandoffPrefix(actorId, handoff, queue, preparation, start) {
|
|
170
221
|
if (handoff.releaseTask !== undefined) {
|
|
171
222
|
return { terminal: handoff.releaseTask };
|
|
@@ -241,6 +292,9 @@ class ZLinkActorHandoffCoordinator {
|
|
|
241
292
|
prepared = undefined;
|
|
242
293
|
};
|
|
243
294
|
return {
|
|
295
|
+
onWithdrawable: (withdraw) => {
|
|
296
|
+
pending.withdraw = withdraw;
|
|
297
|
+
},
|
|
244
298
|
payloadBytes: packetBytes(pending.packet),
|
|
245
299
|
preparation: {
|
|
246
300
|
prepare: async (signal) => {
|
|
@@ -264,6 +318,9 @@ class ZLinkActorHandoffCoordinator {
|
|
|
264
318
|
cancel
|
|
265
319
|
},
|
|
266
320
|
drain: async (replay) => {
|
|
321
|
+
// The FIFO claim, rather than this prefix's eventual terminal,
|
|
322
|
+
// ends the record's durable ownership and transfer capability.
|
|
323
|
+
pending.withdraw = undefined;
|
|
267
324
|
const admission = prepared === undefined
|
|
268
325
|
? undefined
|
|
269
326
|
: (operation) => prepared.run(operation);
|
|
@@ -423,10 +480,22 @@ class ZLinkActorHandoffCoordinator {
|
|
|
423
480
|
}
|
|
424
481
|
}
|
|
425
482
|
capture(origin, actorId, parts, returnResponse = false, remoteBoundSessionTarget, fallbackActorRef, deadlineUnixMs, messageFollowOrigin, provisionalReplay, onAdmitted) {
|
|
426
|
-
|
|
483
|
+
let incomingContext = (0, actor_message_follow_context_1.actorMessageFollowContext)(fallbackActorRef);
|
|
427
484
|
const originalDeadlineUnixMs = deadlineUnixMs ?? incomingContext?.deadlineUnixMs ?? packetDeadlineUnixMs(parts);
|
|
428
|
-
const
|
|
485
|
+
const followRoute = this.findMessageFollowRoute(actorId, incomingContext, messageFollowOrigin?.target);
|
|
486
|
+
// An exact departed tenure belongs to its committed route, even while the
|
|
487
|
+
// same Actor incarnation is performing a later Join on this node.
|
|
488
|
+
const handoff = followRoute === undefined ? this.active.get(actorId) : undefined;
|
|
489
|
+
if (incomingContext === undefined &&
|
|
490
|
+
followRoute !== undefined &&
|
|
491
|
+
messageFollowOrigin?.target !== undefined) {
|
|
492
|
+
incomingContext = this.createInitialIngressContext(followRoute.sourceOwner, messageFollowOrigin.target.actor.generation, parts, returnResponse, originalDeadlineUnixMs, messageFollowOrigin);
|
|
493
|
+
}
|
|
429
494
|
if (handoff !== undefined) {
|
|
495
|
+
if (handoff.phase === 'releasing' &&
|
|
496
|
+
handoff.prefixRelease !== undefined &&
|
|
497
|
+
handoff.pending.at(-1)?.withdraw === undefined)
|
|
498
|
+
return undefined;
|
|
430
499
|
if (parts.length < 2)
|
|
431
500
|
return Promise.resolve(undefined);
|
|
432
501
|
if (handoff.connectionBoundSealed &&
|
|
@@ -442,9 +511,13 @@ class ZLinkActorHandoffCoordinator {
|
|
|
442
511
|
handoff.replay = provisionalReplay;
|
|
443
512
|
}
|
|
444
513
|
const context = incomingContext ??
|
|
445
|
-
this.createInitialIngressContext(handoff.sourceOwner, handoff.oldGeneration, parts, returnResponse, originalDeadlineUnixMs);
|
|
514
|
+
this.createInitialIngressContext(handoff.sourceOwner, handoff.oldGeneration, parts, returnResponse, originalDeadlineUnixMs, messageFollowOrigin);
|
|
446
515
|
try {
|
|
447
516
|
this.validateContext(actorId, context, parts, returnResponse, fallbackActorRef);
|
|
517
|
+
// Accepted handoff retains its original deadline; Message Follow uses a local relay window.
|
|
518
|
+
if (context.deadlineUnixMs !== undefined && Date.now() >= context.deadlineUnixMs) {
|
|
519
|
+
throw actorDeadlineExceeded(actorId);
|
|
520
|
+
}
|
|
448
521
|
}
|
|
449
522
|
catch (error) {
|
|
450
523
|
return Promise.reject(error);
|
|
@@ -473,8 +546,23 @@ class ZLinkActorHandoffCoordinator {
|
|
|
473
546
|
return Promise.resolve(undefined);
|
|
474
547
|
}
|
|
475
548
|
const result = new Promise((resolve, reject) => {
|
|
476
|
-
const
|
|
549
|
+
const original = messageFollowOrigin?.requestSource;
|
|
550
|
+
const originalRidHex = original === undefined ? undefined : (0, routing_id_1.routingIdWireHex)(original.nodeRid);
|
|
551
|
+
const source = original === undefined
|
|
552
|
+
? this.captureRequestSource(handoff.sourceEvidence, context.replyRouteId)
|
|
553
|
+
: {
|
|
554
|
+
ownerId: original.ownerId,
|
|
555
|
+
ownerLeaseGeneration: original.leaseGeneration.toString(),
|
|
556
|
+
nodeRid: String(original.nodeRid),
|
|
557
|
+
...(originalRidHex === undefined ? {} : { nodeRidHex: originalRidHex }),
|
|
558
|
+
nodeGeneration: original.nodeGeneration.toString(),
|
|
559
|
+
replyRouteId: messageFollowOrigin.originalReplyRouteId.toString()
|
|
560
|
+
};
|
|
477
561
|
const requestPacket = { ...packet, source };
|
|
562
|
+
if (original !== undefined) {
|
|
563
|
+
handoff.pending.push({ packet: requestPacket, origin, resolve, reject });
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
478
566
|
const route = {
|
|
479
567
|
actorId,
|
|
480
568
|
operationId: requestPacket.messageFollowContext.operationId,
|
|
@@ -491,7 +579,7 @@ class ZLinkActorHandoffCoordinator {
|
|
|
491
579
|
this.replyRoutes.delete(source.replyRouteId);
|
|
492
580
|
if (!route.delivered)
|
|
493
581
|
route.reject(new Error('Relocation reply route retention expired.'));
|
|
494
|
-
}, RELOCATION_REPLY_RETENTION_MS);
|
|
582
|
+
}, service_stateful_registry_1.RELOCATION_REPLY_RETENTION_MS);
|
|
495
583
|
route.deadline.unref();
|
|
496
584
|
this.replyRoutes.set(source.replyRouteId, route);
|
|
497
585
|
handoff.pending.push({
|
|
@@ -515,7 +603,6 @@ class ZLinkActorHandoffCoordinator {
|
|
|
515
603
|
}
|
|
516
604
|
return result;
|
|
517
605
|
}
|
|
518
|
-
const followRoute = this.findMessageFollowRoute(actorId, incomingContext);
|
|
519
606
|
const staleGeneration = fallbackActorRef?.objectGeneration;
|
|
520
607
|
if (fallbackActorRef !== undefined &&
|
|
521
608
|
this.options.isCurrentActorRef?.(actorId, fallbackActorRef) === true) {
|
|
@@ -589,16 +676,6 @@ class ZLinkActorHandoffCoordinator {
|
|
|
589
676
|
handoff.snapshotIndex = handoff.pending.length - 1;
|
|
590
677
|
return handoff.pending.map((entry) => entry.packet);
|
|
591
678
|
}
|
|
592
|
-
snapshotCoreBacklog(actorId) {
|
|
593
|
-
const handoff = this.requireActive(actorId);
|
|
594
|
-
let snapshotIndex = -1;
|
|
595
|
-
while (snapshotIndex + 1 < handoff.pending.length &&
|
|
596
|
-
handoff.pending[snapshotIndex + 1].packet.returnResponse === false) {
|
|
597
|
-
snapshotIndex++;
|
|
598
|
-
}
|
|
599
|
-
handoff.snapshotIndex = snapshotIndex;
|
|
600
|
-
return handoff.pending.slice(0, snapshotIndex + 1).map((entry) => entry.packet);
|
|
601
|
-
}
|
|
602
679
|
/**
|
|
603
680
|
* Freezes the post-capture ingress segment immediately before the caller
|
|
604
681
|
* appends the one-way cutover on the same relocation lane. Records returned
|
|
@@ -613,11 +690,22 @@ class ZLinkActorHandoffCoordinator {
|
|
|
613
690
|
}
|
|
614
691
|
complete(actorId, target, targetActorRef, results, targetOwnerFence) {
|
|
615
692
|
const handoff = this.requireActive(actorId);
|
|
616
|
-
const committedTargetOwner = requireExactTargetOwnerFence(actorId, targetOwnerFence);
|
|
693
|
+
const committedTargetOwner = targetOwnerFence === null ? null : requireExactTargetOwnerFence(actorId, targetOwnerFence);
|
|
617
694
|
this.active.delete(actorId);
|
|
695
|
+
// Location runtime §10: a later owner has no source-local Follow route.
|
|
696
|
+
if (committedTargetOwner === null) {
|
|
697
|
+
const unavailable = actorLocationStale(actorId);
|
|
698
|
+
for (const pending of handoff.pending)
|
|
699
|
+
this.failReleasedPending(pending, unavailable);
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
618
702
|
const byIndex = new Map(results.map((result) => [result.index, result]));
|
|
619
703
|
for (let i = 0; i <= handoff.snapshotIndex; i++) {
|
|
620
704
|
const pending = handoff.pending[i];
|
|
705
|
+
if (pending.packet.messageFollowOrigin?.requestSource !== undefined) {
|
|
706
|
+
pending.resolve?.(exports.RELOCATED_REQUEST_OWNED_BY_REQUESTER);
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
621
709
|
if (pending.packet.source !== undefined)
|
|
622
710
|
continue;
|
|
623
711
|
const result = byIndex.get(pending.packet.index);
|
|
@@ -655,15 +743,25 @@ class ZLinkActorHandoffCoordinator {
|
|
|
655
743
|
}
|
|
656
744
|
}
|
|
657
745
|
messageFollowCount(actorId) {
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
746
|
+
let count = 0;
|
|
747
|
+
if (actorId === undefined) {
|
|
748
|
+
for (const id of this.messageFollowRoutes.keys())
|
|
749
|
+
count += this.messageFollowCount(id);
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
const routes = this.messageFollowRoutes.get(actorId);
|
|
753
|
+
if (routes !== undefined) {
|
|
754
|
+
for (const owners of routes.values())
|
|
755
|
+
count += owners.size;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
return count;
|
|
661
759
|
}
|
|
662
760
|
pendingCount(actorId) {
|
|
663
761
|
return this.active.get(actorId)?.pending.length ?? 0;
|
|
664
762
|
}
|
|
665
763
|
isKnownStale(actor) {
|
|
666
|
-
return (this.
|
|
764
|
+
return (!this.messageFollowRoutes.has(actor.actorId) &&
|
|
667
765
|
this.options.isCurrentActorRef?.(actor.actorId, actor) !== true &&
|
|
668
766
|
this.isKnownStaleRef(actor.actorId, actor));
|
|
669
767
|
}
|
|
@@ -782,8 +880,18 @@ class ZLinkActorHandoffCoordinator {
|
|
|
782
880
|
refs.set(exactRefKey, departedAuthorityOwnerGeneration);
|
|
783
881
|
}
|
|
784
882
|
}
|
|
785
|
-
const key = messageFollowRouteKey(
|
|
786
|
-
|
|
883
|
+
const key = messageFollowRouteKey(oldGeneration, sourceOwner.nodeRidHex ?? (0, routing_id_1.encodeRoutingIdStorageHex)(sourceOwner.nodeRid), sourceOwner.nodeGeneration, sourceOwner.authorityOwnerGeneration, sourceOwner.ownerLeaseGeneration);
|
|
884
|
+
let routes = this.messageFollowRoutes.get(actorId);
|
|
885
|
+
if (routes === undefined) {
|
|
886
|
+
routes = new Map();
|
|
887
|
+
this.messageFollowRoutes.set(actorId, routes);
|
|
888
|
+
}
|
|
889
|
+
let owners = routes.get(key);
|
|
890
|
+
if (owners === undefined) {
|
|
891
|
+
owners = new Map();
|
|
892
|
+
routes.set(key, owners);
|
|
893
|
+
}
|
|
894
|
+
const previous = owners.get(sourceOwner.ownerId);
|
|
787
895
|
if (previous !== undefined)
|
|
788
896
|
clearTimeout(previous.deadline);
|
|
789
897
|
const suppressionFence = actorMessageFollowSuppressionFence(actorId, oldGeneration, sourceOwner, targetOwner);
|
|
@@ -813,15 +921,24 @@ class ZLinkActorHandoffCoordinator {
|
|
|
813
921
|
else {
|
|
814
922
|
this.messageFollowSuppression.replaceRoute(previous.suppressionFence, suppressionFence);
|
|
815
923
|
}
|
|
816
|
-
|
|
924
|
+
owners.set(sourceOwner.ownerId, entry);
|
|
817
925
|
this.options.onMarker?.('message_follow_registered', actorId, this.messageFollowDurationMs);
|
|
818
926
|
return entry;
|
|
819
927
|
}
|
|
820
928
|
removeMessageFollowRoute(entry) {
|
|
821
|
-
|
|
929
|
+
const actorId = entry.targetActorRef.actorId;
|
|
930
|
+
const routes = this.messageFollowRoutes.get(actorId);
|
|
931
|
+
if (routes === undefined)
|
|
932
|
+
return;
|
|
933
|
+
const owners = routes.get(entry.key);
|
|
934
|
+
if (owners?.get(entry.sourceOwner.ownerId) !== entry)
|
|
822
935
|
return;
|
|
823
936
|
clearTimeout(entry.deadline);
|
|
824
|
-
|
|
937
|
+
owners.delete(entry.sourceOwner.ownerId);
|
|
938
|
+
if (owners.size === 0)
|
|
939
|
+
routes.delete(entry.key);
|
|
940
|
+
if (routes.size === 0)
|
|
941
|
+
this.messageFollowRoutes.delete(actorId);
|
|
825
942
|
this.messageFollowSuppression.expireRoute(entry.suppressionFence);
|
|
826
943
|
this.pruneStaleTenureRecords(entry);
|
|
827
944
|
this.options.onMarker?.('message_follow_route_removed', entry.targetActorRef.actorId);
|
|
@@ -858,19 +975,48 @@ class ZLinkActorHandoffCoordinator {
|
|
|
858
975
|
if (refs.size === 0)
|
|
859
976
|
this.staleActorRefs.delete(actorId);
|
|
860
977
|
}
|
|
861
|
-
findMessageFollowRoute(actorId, context) {
|
|
862
|
-
|
|
978
|
+
findMessageFollowRoute(actorId, context, nativeTarget) {
|
|
979
|
+
const routes = this.messageFollowRoutes.get(actorId);
|
|
980
|
+
if (routes === undefined)
|
|
863
981
|
return undefined;
|
|
864
|
-
|
|
982
|
+
if (context === undefined) {
|
|
983
|
+
if (nativeTarget === undefined || nativeTarget.actor.actorId !== actorId)
|
|
984
|
+
return undefined;
|
|
985
|
+
return routes
|
|
986
|
+
.get(messageFollowRouteKey(nativeTarget.actor.generation, (0, routing_id_1.encodeRoutingIdStorageHex)(nativeTarget.actor.nodeRid), nativeTarget.targetNodeGeneration, nativeTarget.authorityOwnerGeneration, nativeTarget.ownerLeaseGeneration))
|
|
987
|
+
?.values()
|
|
988
|
+
.next().value;
|
|
989
|
+
}
|
|
990
|
+
const owner = context.targetOwner;
|
|
991
|
+
return routes
|
|
992
|
+
.get(messageFollowRouteKey(BigInt(context.objectGeneration), owner.nodeRidHex ?? (0, routing_id_1.encodeRoutingIdStorageHex)(owner.nodeRid), owner.nodeGeneration, owner.authorityOwnerGeneration, owner.ownerLeaseGeneration))
|
|
993
|
+
?.get(owner.ownerId);
|
|
865
994
|
}
|
|
866
995
|
hasMessageFollowRouteForStaleRef(actorId, actorRef) {
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
996
|
+
const routes = this.messageFollowRoutes.get(actorId);
|
|
997
|
+
if (routes === undefined)
|
|
998
|
+
return false;
|
|
999
|
+
for (const owners of routes.values()) {
|
|
1000
|
+
for (const route of owners.values()) {
|
|
1001
|
+
if (actorRef.objectGeneration === route.oldGeneration &&
|
|
1002
|
+
(route.oldNodeRid === undefined ||
|
|
1003
|
+
(0, routing_id_1.routingIdsEqual)(actorRef.nodeRid, (0, actor_message_follow_context_1.messageFollowOwnerNodeRid)(route.sourceOwner))))
|
|
1004
|
+
return true;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
return false;
|
|
871
1008
|
}
|
|
872
|
-
createInitialIngressContext(sourceOwner, generation, parts, request, deadlineUnixMs) {
|
|
873
|
-
|
|
1009
|
+
createInitialIngressContext(sourceOwner, generation, parts, request, deadlineUnixMs, origin) {
|
|
1010
|
+
let operationId;
|
|
1011
|
+
if (origin === undefined) {
|
|
1012
|
+
operationId = (0, actor_message_follow_context_1.createMessageFollowId)();
|
|
1013
|
+
}
|
|
1014
|
+
else {
|
|
1015
|
+
const bytes = Buffer.allocUnsafe(operation_identity_1.OPERATION_IDENTITY_BYTES);
|
|
1016
|
+
bytes.writeBigUInt64BE(BigInt.asUintN(stream_wire_1.UINT64_BYTES * 8, origin.originalOperation.high));
|
|
1017
|
+
bytes.writeBigUInt64BE(BigInt.asUintN(stream_wire_1.UINT64_BYTES * 8, origin.originalOperation.low), stream_wire_1.UINT64_BYTES);
|
|
1018
|
+
operationId = bytes.toString('hex');
|
|
1019
|
+
}
|
|
874
1020
|
return Object.freeze({
|
|
875
1021
|
operationId,
|
|
876
1022
|
objectGeneration: generation.toString(),
|
|
@@ -878,7 +1024,11 @@ class ZLinkActorHandoffCoordinator {
|
|
|
878
1024
|
targetOwner: sourceOwner,
|
|
879
1025
|
deadlineUnixMs,
|
|
880
1026
|
correlationId: request ? (0, actor_message_follow_context_1.createMessageFollowId)() : undefined,
|
|
881
|
-
replyRouteId: request
|
|
1027
|
+
replyRouteId: request
|
|
1028
|
+
? origin === undefined
|
|
1029
|
+
? (0, actor_message_follow_context_1.createMessageFollowId)()
|
|
1030
|
+
: operationId
|
|
1031
|
+
: undefined,
|
|
882
1032
|
request,
|
|
883
1033
|
hopCount: 0,
|
|
884
1034
|
visitedOwners: Object.freeze([(0, actor_message_follow_context_1.messageFollowOwnerFenceKey)(sourceOwner)]),
|
|
@@ -893,9 +1043,6 @@ class ZLinkActorHandoffCoordinator {
|
|
|
893
1043
|
if (context.objectGeneration === '0' || context.request !== request) {
|
|
894
1044
|
throw actorLocationStale(actorId);
|
|
895
1045
|
}
|
|
896
|
-
if (context.deadlineUnixMs !== undefined && Date.now() >= context.deadlineUnixMs) {
|
|
897
|
-
throw actorDeadlineExceeded(actorId);
|
|
898
|
-
}
|
|
899
1046
|
(0, actor_message_follow_context_1.verifyActorMessageFollowPayload)(context, parts);
|
|
900
1047
|
}
|
|
901
1048
|
isKnownStaleRef(actorId, actor) {
|
|
@@ -928,7 +1075,8 @@ class ZLinkActorHandoffCoordinator {
|
|
|
928
1075
|
return BigInt(context.targetOwner.authorityOwnerGeneration);
|
|
929
1076
|
}
|
|
930
1077
|
const current = this.options.currentOwnerFence?.(actorId);
|
|
931
|
-
if (current !== undefined &&
|
|
1078
|
+
if (current !== undefined &&
|
|
1079
|
+
(0, routing_id_1.routingIdsEqual)((0, actor_message_follow_context_1.messageFollowOwnerNodeRid)(current), actor.nodeRid)) {
|
|
932
1080
|
return BigInt(current.authorityOwnerGeneration);
|
|
933
1081
|
}
|
|
934
1082
|
return undefined;
|
|
@@ -1011,19 +1159,20 @@ class ZLinkActorHandoffCoordinator {
|
|
|
1011
1159
|
await this.messageFollowRelayed(actorId, entry, packet, advanced);
|
|
1012
1160
|
return undefined;
|
|
1013
1161
|
}
|
|
1014
|
-
const
|
|
1162
|
+
const timeoutMs = this.options.requestTimeoutMs ?? Registration_1.DEFAULT_REQUEST_TIMEOUT_MS;
|
|
1163
|
+
const relayDeadlineMs = performance.now() + timeoutMs;
|
|
1015
1164
|
if (this.options.routedTransport.requestRawToSpot === undefined) {
|
|
1016
|
-
const reply = await
|
|
1165
|
+
const reply = await (0, request_deadline_1.waitRequestReply)(this.options.routedTransport.requestToSpot(target, payload, {
|
|
1017
1166
|
packetName: actor_packet_relay_wire_1.ZLINK_REMOTE_ACTOR_PACKET_RELAY_PACKET,
|
|
1018
|
-
timeoutMs
|
|
1019
|
-
}), actorId,
|
|
1167
|
+
timeoutMs
|
|
1168
|
+
}), actorId, relayDeadlineMs);
|
|
1020
1169
|
if (reply.ok === false) {
|
|
1021
1170
|
throw actorRelayError(actorId, reply.errorKind, reply.error);
|
|
1022
1171
|
}
|
|
1023
1172
|
await this.messageFollowRelayed(actorId, entry, packet, advanced);
|
|
1024
1173
|
return reply.response;
|
|
1025
1174
|
}
|
|
1026
|
-
const response = await
|
|
1175
|
+
const response = await (0, request_deadline_1.waitRequestReply)((0, actor_routed_json_request_1.requestRoutedJsonReply)(this.options.routedTransport, target, payload, { timeoutMs }, `Actor Message Follow raw request is not available for '${actorId}'.`, (parts) => {
|
|
1027
1176
|
if (parts.length === 0) {
|
|
1028
1177
|
throw new Error(`Actor Message Follow reply was empty for '${actorId}'.`);
|
|
1029
1178
|
}
|
|
@@ -1032,7 +1181,7 @@ class ZLinkActorHandoffCoordinator {
|
|
|
1032
1181
|
throw actorRelayError(actorId, reply.errorKind, reply.error);
|
|
1033
1182
|
}
|
|
1034
1183
|
return reply.response;
|
|
1035
|
-
}), actorId,
|
|
1184
|
+
}), actorId, relayDeadlineMs);
|
|
1036
1185
|
await this.messageFollowRelayed(actorId, entry, packet, advanced);
|
|
1037
1186
|
return response;
|
|
1038
1187
|
}
|
|
@@ -1180,31 +1329,6 @@ function packetDeadlineUnixMs(parts) {
|
|
|
1180
1329
|
return undefined;
|
|
1181
1330
|
}
|
|
1182
1331
|
}
|
|
1183
|
-
function remainingRequestTime(actorId, deadlineUnixMs) {
|
|
1184
|
-
if (deadlineUnixMs === undefined)
|
|
1185
|
-
return undefined;
|
|
1186
|
-
const remaining = deadlineUnixMs - Date.now();
|
|
1187
|
-
if (remaining <= 0)
|
|
1188
|
-
throw actorDeadlineExceeded(actorId);
|
|
1189
|
-
return Math.max(1, Math.ceil(remaining));
|
|
1190
|
-
}
|
|
1191
|
-
async function awaitBeforeDeadline(operation, actorId, remainingMs) {
|
|
1192
|
-
if (remainingMs === undefined)
|
|
1193
|
-
return await operation;
|
|
1194
|
-
let timer;
|
|
1195
|
-
try {
|
|
1196
|
-
return await Promise.race([
|
|
1197
|
-
operation,
|
|
1198
|
-
new Promise((_resolve, reject) => {
|
|
1199
|
-
timer = setTimeout(() => reject(actorDeadlineExceeded(actorId)), remainingMs);
|
|
1200
|
-
})
|
|
1201
|
-
]);
|
|
1202
|
-
}
|
|
1203
|
-
finally {
|
|
1204
|
-
if (timer !== undefined)
|
|
1205
|
-
clearTimeout(timer);
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
1332
|
async function waitForHandoffReplayStart(start, signal) {
|
|
1209
1333
|
if (signal.aborted)
|
|
1210
1334
|
throw signal.reason;
|
|
@@ -1220,8 +1344,8 @@ async function waitForHandoffReplayStart(start, signal) {
|
|
|
1220
1344
|
signal.removeEventListener('abort', abort);
|
|
1221
1345
|
}
|
|
1222
1346
|
}
|
|
1223
|
-
function messageFollowRouteKey(
|
|
1224
|
-
return `${
|
|
1347
|
+
function messageFollowRouteKey(objectGeneration, nodeRidHex, nodeGeneration, authorityOwnerGeneration, ownerLeaseGeneration) {
|
|
1348
|
+
return `${objectGeneration}\u0000${nodeRidHex}\u0000${nodeGeneration}\u0000${authorityOwnerGeneration}\u0000${ownerLeaseGeneration}`;
|
|
1225
1349
|
}
|
|
1226
1350
|
function actorRefKey(nodeRid, generation) {
|
|
1227
1351
|
return `${(0, routing_id_1.encodeRoutingIdStorageHex)(nodeRid)}\u0000${generation}`;
|
|
@@ -1233,7 +1357,7 @@ function requestSourcesEqual(expected, actual) {
|
|
|
1233
1357
|
return (expected.replyRouteId === actual.replyRouteId &&
|
|
1234
1358
|
expected.ownerId === actual.ownerId &&
|
|
1235
1359
|
expected.ownerLeaseGeneration === actual.ownerLeaseGeneration &&
|
|
1236
|
-
expected.nodeRid
|
|
1360
|
+
(0, routing_id_1.routingIdsEqual)((0, routing_id_1.decodeRoutingId)(expected.nodeRid, expected.nodeRidHex), (0, routing_id_1.decodeRoutingId)(actual.nodeRid, actual.nodeRidHex)) &&
|
|
1237
1361
|
expected.nodeGeneration === actual.nodeGeneration &&
|
|
1238
1362
|
/^[1-9][0-9]*$/.test(actual.ownerLeaseGeneration) &&
|
|
1239
1363
|
/^[1-9][0-9]*$/.test(actual.nodeGeneration));
|
|
@@ -32,6 +32,8 @@ export interface ZLinkActorJoinRelocation {
|
|
|
32
32
|
readonly deadlineAtMs?: number;
|
|
33
33
|
readonly signal?: AbortSignal;
|
|
34
34
|
}): Promise<{
|
|
35
|
+
/** Source-only terminal after relay readiness transferred public completion. */
|
|
36
|
+
readonly sourceCleanup?: () => Promise<void>;
|
|
35
37
|
readonly actorRef: ZLinkBackendActorRef;
|
|
36
38
|
readonly membershipEpoch: bigint;
|
|
37
39
|
readonly spotGeneration: bigint;
|
|
@@ -248,6 +248,10 @@ class ZLinkLocalNativeActorJoin {
|
|
|
248
248
|
admission.parts[0]?.close();
|
|
249
249
|
throw error;
|
|
250
250
|
}
|
|
251
|
+
if (relocated.sourceCleanup !== undefined) {
|
|
252
|
+
admission.parts[0]?.close();
|
|
253
|
+
return { accepted: false, sourceCleanup: relocated.sourceCleanup };
|
|
254
|
+
}
|
|
251
255
|
state.setNativeActorRef(relocated.actorRef);
|
|
252
256
|
if (entrySpot) {
|
|
253
257
|
state.clearJoinedSpot();
|
|
@@ -14,8 +14,34 @@ class ZLinkActorSerialExecutor {
|
|
|
14
14
|
this.scheduler = new serial_execution_queue_1.ZLinkSerialExecutionQueue((record) => this.runRecord(record), options, sharedOwner);
|
|
15
15
|
}
|
|
16
16
|
execute(operation, workOptions) {
|
|
17
|
+
const initial = (0, application_job_queue_scope_1.currentApplicationJobPermit)();
|
|
18
|
+
if (initial !== undefined &&
|
|
19
|
+
workOptions?.lane !== 'lifecycle' &&
|
|
20
|
+
this.scheduler.hasPendingDurableApplication) {
|
|
21
|
+
let prepared;
|
|
22
|
+
const cancel = () => {
|
|
23
|
+
prepared?.releaseAfterInternalProcessing();
|
|
24
|
+
prepared = undefined;
|
|
25
|
+
};
|
|
26
|
+
const terminal = this.scheduler.admitDurablePrefix(() => (0, application_job_queue_scope_1.runWithApplicationJobPermit)(prepared, () => (0, actor_execution_context_1.runZLinkActorExecution)(this.actorId, this.sourceSpotId, operation)), workOptions, undefined, {
|
|
27
|
+
prepare: async (signal) => {
|
|
28
|
+
if (initial.reacquire === undefined) {
|
|
29
|
+
throw new Error('Durable Actor ingress requires its host permit source.');
|
|
30
|
+
}
|
|
31
|
+
prepared = await initial.reacquire(signal);
|
|
32
|
+
if (signal.aborted) {
|
|
33
|
+
cancel();
|
|
34
|
+
throw signal.reason;
|
|
35
|
+
}
|
|
36
|
+
prepared.markApplicationQueued();
|
|
37
|
+
},
|
|
38
|
+
cancel
|
|
39
|
+
});
|
|
40
|
+
initial.releaseAfterInternalProcessing();
|
|
41
|
+
return terminal;
|
|
42
|
+
}
|
|
17
43
|
const boundOperation = (0, application_job_queue_scope_1.bindApplicationJobPermit)(() => (0, actor_execution_context_1.runZLinkActorExecution)(this.actorId, this.sourceSpotId, operation));
|
|
18
|
-
return
|
|
44
|
+
return initial !== undefined
|
|
19
45
|
? this.scheduler.submitPreAdmitted(boundOperation, workOptions)
|
|
20
46
|
: this.scheduler.submit(boundOperation, workOptions);
|
|
21
47
|
}
|
|
@@ -78,7 +78,9 @@ class ZLinkActorNativeJoinCoordinator {
|
|
|
78
78
|
return this.withDeferredJoinFinalizer(actor, state, target, result, completionOperationId);
|
|
79
79
|
}
|
|
80
80
|
withDeferredJoinFinalizer(actor, state, target, result, operationId) {
|
|
81
|
-
if (
|
|
81
|
+
if (result.sourceCleanup !== undefined ||
|
|
82
|
+
operationId === undefined ||
|
|
83
|
+
this.options.sourceTransfer === undefined)
|
|
82
84
|
return result;
|
|
83
85
|
return {
|
|
84
86
|
...result,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { encodeFrameworkPayload } from '../messaging/payload-codec';
|
|
2
|
+
import { ZLinkStreamMessageKind } from '../streams/protocol';
|
|
3
|
+
/** Ordinary dispatch and relocation use the same typed Actor reply envelope. */
|
|
4
|
+
export declare function encodeActorReply(requestHeaderBytes: Uint8Array, kind: ZLinkStreamMessageKind.Response | ZLinkStreamMessageKind.Error, payload: unknown, serializers: Parameters<typeof encodeFrameworkPayload>[1], flowEnabled: boolean): readonly Buffer[];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.encodeActorReply = encodeActorReply;
|
|
4
|
+
const payload_codec_1 = require("../messaging/payload-codec");
|
|
5
|
+
const protocol_1 = require("../streams/protocol");
|
|
6
|
+
/** Ordinary dispatch and relocation use the same typed Actor reply envelope. */
|
|
7
|
+
function encodeActorReply(requestHeaderBytes, kind, payload, serializers, flowEnabled) {
|
|
8
|
+
const requestHeader = (0, protocol_1.decodeStreamHeader)(requestHeaderBytes, flowEnabled);
|
|
9
|
+
const encoded = kind === protocol_1.ZLinkStreamMessageKind.Response
|
|
10
|
+
? (0, payload_codec_1.encodeFrameworkPayload)(payload, serializers, requestHeader.name, 'reply')
|
|
11
|
+
: (0, payload_codec_1.encodeFrameworkPayload)(payload);
|
|
12
|
+
try {
|
|
13
|
+
const frame = (0, protocol_1.encodeStreamFrame)({
|
|
14
|
+
kind,
|
|
15
|
+
codec: (0, protocol_1.streamCodecForContentType)(encoded.contentType),
|
|
16
|
+
flags: protocol_1.ZLinkStreamHeaderFlags.None,
|
|
17
|
+
requestSeq: requestHeader.requestSeq,
|
|
18
|
+
name: '',
|
|
19
|
+
metadata: new Map(),
|
|
20
|
+
correlationId: requestHeader.correlationId,
|
|
21
|
+
flowId: requestHeader.flowId,
|
|
22
|
+
flowOrigin: requestHeader.flowOrigin
|
|
23
|
+
}, encoded.message.data());
|
|
24
|
+
return [Buffer.from(frame.buffer, frame.byteOffset, frame.byteLength)];
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
encoded.message.close();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -8,6 +8,8 @@ import type { ZLinkActorTransferRegistry } from './actor-transfer-registry';
|
|
|
8
8
|
import type { ZLinkRuntimeAdmissionGate } from '../admission';
|
|
9
9
|
import type { ZLinkActivationAdmission } from '../activation-admission';
|
|
10
10
|
export interface ZLinkActorJoinRuntimeResult<TReply> {
|
|
11
|
+
/** Relay-ready transferred completion; this continuation only releases source work. */
|
|
12
|
+
readonly sourceCleanup?: () => Promise<void>;
|
|
11
13
|
readonly accepted: boolean;
|
|
12
14
|
readonly actor?: import('../../contracts').ActorRef;
|
|
13
15
|
readonly reply?: TReply;
|