@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,3 +1,4 @@
|
|
|
1
|
+
import type { ZLinkMeshDispatchAdmission } from '../admission';
|
|
1
2
|
import type { ApplicationJobOrigin } from '../application-jobs/contracts';
|
|
2
3
|
import { RuntimeDisposal } from '../disposal';
|
|
3
4
|
import { randomUUID } from 'node:crypto';
|
|
@@ -34,7 +35,7 @@ import {
|
|
|
34
35
|
import { ZLinkLocationWriteIntent, ZLinkLocationWriteStatus } from '../../contracts/Locations';
|
|
35
36
|
import type { ZLinkLocationOptionOverrides } from '../../contracts/Locations/Options';
|
|
36
37
|
import type { ZLinkLocationOwnerToken } from '../../contracts/Locations/Writes';
|
|
37
|
-
import { createAbortError } from '../abort';
|
|
38
|
+
import { awaitWithAbort, createAbortError } from '../abort';
|
|
38
39
|
import type { ZLinkActivationConcurrency } from '../activation-admission';
|
|
39
40
|
import type { ZLinkRemoteBoundSessionTarget } from '../actors';
|
|
40
41
|
import type { ZLinkActorHandoffPacket } from '../actors/actor-handoff';
|
|
@@ -205,6 +206,12 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
205
206
|
);
|
|
206
207
|
}
|
|
207
208
|
|
|
209
|
+
async requestPeerReconcile(meshName: string, peerRid: string): Promise<void> {
|
|
210
|
+
await Promise.all(
|
|
211
|
+
this.autoConnectLoops.map((loop) => loop.requestPeerReconcile(meshName, peerRid))
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
208
215
|
async startLocationAutoConnect(signal?: AbortSignal): Promise<void> {
|
|
209
216
|
const location = this.locationAutoConnect;
|
|
210
217
|
if (location === undefined || this.autoConnectLoops.length > 0) {
|
|
@@ -218,6 +225,16 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
218
225
|
}
|
|
219
226
|
const capability = spotNodeAutoConnectCapability(spotNodeName, spotNode, node);
|
|
220
227
|
if (capability === undefined) continue;
|
|
228
|
+
node.setRequestSourceAcceptance?.(
|
|
229
|
+
(nodeRid, nodeGeneration, nodeRidStorageHex, sourceSignal) =>
|
|
230
|
+
location.requestSources.accept(
|
|
231
|
+
capability.local.meshName,
|
|
232
|
+
nodeRid,
|
|
233
|
+
nodeGeneration,
|
|
234
|
+
nodeRidStorageHex,
|
|
235
|
+
sourceSignal
|
|
236
|
+
)
|
|
237
|
+
);
|
|
221
238
|
const reconciler = new ZLinkAutoConnectReconciler({
|
|
222
239
|
local: capability.local,
|
|
223
240
|
localRow: capability.localRow,
|
|
@@ -292,6 +309,24 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
292
309
|
if (this.options.dispatchErrors !== undefined) {
|
|
293
310
|
node.setDispatchErrorReporter?.(this.options.dispatchErrors, spotNodeName);
|
|
294
311
|
}
|
|
312
|
+
// Session-Actor binding §4: the Session owner identity comes from the
|
|
313
|
+
// host's own descriptor or from a peer descriptor that passed the
|
|
314
|
+
// Location runtime §4.1 owner lease check.
|
|
315
|
+
node.setSessionOwnerDescriptors?.({
|
|
316
|
+
local: () => this.locationAutoConnect?.runtime.currentOwnerToken,
|
|
317
|
+
peer: async (peerRid, peerGeneration) => {
|
|
318
|
+
const location = this.locationAutoConnect;
|
|
319
|
+
if (location === undefined) return undefined;
|
|
320
|
+
const descriptor = (await location.runtime.listLiveMeshNodes(spotNodeName)).find(
|
|
321
|
+
(candidate) =>
|
|
322
|
+
routingIdsEqual(candidate.rid, peerRid) &&
|
|
323
|
+
candidate.lifecycleGeneration === peerGeneration
|
|
324
|
+
);
|
|
325
|
+
return descriptor === undefined
|
|
326
|
+
? undefined
|
|
327
|
+
: { ownerId: descriptor.ownerId, leaseGeneration: descriptor.leaseGeneration };
|
|
328
|
+
}
|
|
329
|
+
});
|
|
295
330
|
node.setMailboxRecordDroppedHandler?.((record) =>
|
|
296
331
|
this.options.dispatchErrors?.report({
|
|
297
332
|
surface: ZLinkDispatchErrorSurface.RouteMeshChannel,
|
|
@@ -412,7 +447,7 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
412
447
|
this.meshNodes.delete(spotNodeName);
|
|
413
448
|
completions.dispose(error);
|
|
414
449
|
await pump?.dispose();
|
|
415
|
-
node.close();
|
|
450
|
+
await node.close();
|
|
416
451
|
throw error;
|
|
417
452
|
}
|
|
418
453
|
}
|
|
@@ -447,9 +482,8 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
447
482
|
const ownerChanged =
|
|
448
483
|
this.publishedOwnerToken !== undefined && !sameOwnerToken(this.publishedOwnerToken, owner);
|
|
449
484
|
if (ownerChanged) {
|
|
450
|
-
// A
|
|
451
|
-
//
|
|
452
|
-
// Renew against a row that no longer exists.
|
|
485
|
+
// A descriptor confirmed under the previous lease must not supply
|
|
486
|
+
// cached population data for a new owner token.
|
|
453
487
|
this.publishedMeshNodeDescriptors.clear();
|
|
454
488
|
}
|
|
455
489
|
for (const [meshName, registration] of this.options.registration.spotNodes) {
|
|
@@ -467,7 +501,14 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
467
501
|
...instanceSpots.map(([stableType, factory]) =>
|
|
468
502
|
objectCapability('instance_spot', stableType, factory)
|
|
469
503
|
),
|
|
470
|
-
...actors.map(([stableType, factory]) =>
|
|
504
|
+
...actors.map(([stableType, factory]) =>
|
|
505
|
+
objectCapability(
|
|
506
|
+
'actor',
|
|
507
|
+
stableType,
|
|
508
|
+
factory,
|
|
509
|
+
registrationAcceptsNewActor(registration, stableType)
|
|
510
|
+
)
|
|
511
|
+
)
|
|
471
512
|
].sort((left, right) => {
|
|
472
513
|
const kindOrder = left.objectKind.localeCompare(right.objectKind);
|
|
473
514
|
return kindOrder !== 0 ? kindOrder : left.stableType.localeCompare(right.stableType);
|
|
@@ -482,9 +523,8 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
482
523
|
// The raw MeshNode resolves port zero and applies AdvertiseHost once.
|
|
483
524
|
// Discovery and RouteMesh hello must publish that same public identity.
|
|
484
525
|
endpoint: status.localEndpoint,
|
|
485
|
-
|
|
526
|
+
...this.localDescriptorFields(meshName, registration, state),
|
|
486
527
|
entrySpotId: this.entrySpotId(meshName, registration),
|
|
487
|
-
placementWeight: this.placementWeight(meshName),
|
|
488
528
|
populationCapacity: {
|
|
489
529
|
actors: {
|
|
490
530
|
active: current?.populationCapacity.actors.active ?? 0,
|
|
@@ -517,19 +557,6 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
517
557
|
active: 0,
|
|
518
558
|
limit: registration.activationConcurrencyLimit ?? DEFAULT_ACTIVATION_CONCURRENCY_LIMIT
|
|
519
559
|
},
|
|
520
|
-
channelWeights: Object.fromEntries(
|
|
521
|
-
this.serverChannels(meshName).map(([channelName, channel]) => [
|
|
522
|
-
channelName,
|
|
523
|
-
state === ZLinkFrameworkRuntimeState.Draining
|
|
524
|
-
? 0
|
|
525
|
-
: this.effectiveChannelWeight(
|
|
526
|
-
meshName,
|
|
527
|
-
channelName,
|
|
528
|
-
channel.weight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT
|
|
529
|
-
)
|
|
530
|
-
])
|
|
531
|
-
),
|
|
532
|
-
applicationVersion: this.options.registration.applicationVersion,
|
|
533
560
|
maintenanceWave: this.options.registration.maintenanceWave,
|
|
534
561
|
spotTypes: [
|
|
535
562
|
...userSpots.map(([stableType]) => stableType),
|
|
@@ -540,13 +567,14 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
540
567
|
state,
|
|
541
568
|
securityIdentity: 'default'
|
|
542
569
|
};
|
|
570
|
+
// Revision is issued before submission: an unconfirmed Store write may
|
|
571
|
+
// already have applied, so the next publication must not reuse it.
|
|
572
|
+
this.descriptorRevisionByMesh.set(meshName, descriptor.descriptorRevision);
|
|
543
573
|
const result = await location.runtime.writeMeshNode(
|
|
544
574
|
descriptor,
|
|
545
|
-
|
|
546
|
-
? ZLinkLocationWriteIntent.
|
|
547
|
-
:
|
|
548
|
-
? ZLinkLocationWriteIntent.NewClaim
|
|
549
|
-
: ZLinkLocationWriteIntent.Renew,
|
|
575
|
+
previousRevision === 0n
|
|
576
|
+
? ZLinkLocationWriteIntent.NewClaim
|
|
577
|
+
: ZLinkLocationWriteIntent.Renew,
|
|
550
578
|
signal
|
|
551
579
|
);
|
|
552
580
|
if (result.status !== ZLinkLocationWriteStatus.Stored) {
|
|
@@ -560,11 +588,37 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
560
588
|
leaseGeneration: location.runtime.currentOwnerToken!.leaseGeneration,
|
|
561
589
|
updatedAt: result.updatedAt
|
|
562
590
|
});
|
|
563
|
-
this.descriptorRevisionByMesh.set(meshName, descriptor.descriptorRevision);
|
|
564
591
|
}
|
|
565
592
|
this.publishedOwnerToken = owner;
|
|
566
593
|
}
|
|
567
594
|
|
|
595
|
+
private localDescriptorFields(
|
|
596
|
+
meshName: string,
|
|
597
|
+
registration: ZLinkSpotNodeOptions,
|
|
598
|
+
state: ZLinkFrameworkRuntimeState
|
|
599
|
+
): Pick<
|
|
600
|
+
ZLinkMeshNodeDescriptor,
|
|
601
|
+
'objectRole' | 'placementWeight' | 'channelWeights' | 'applicationVersion'
|
|
602
|
+
> {
|
|
603
|
+
return {
|
|
604
|
+
objectRole: effectiveObjectRole(registration),
|
|
605
|
+
placementWeight: this.placementWeight(meshName),
|
|
606
|
+
channelWeights: Object.fromEntries(
|
|
607
|
+
this.serverChannels(meshName).map(([channelName, channel]) => [
|
|
608
|
+
channelName,
|
|
609
|
+
state === ZLinkFrameworkRuntimeState.Draining
|
|
610
|
+
? 0
|
|
611
|
+
: this.effectiveChannelWeight(
|
|
612
|
+
meshName,
|
|
613
|
+
channelName,
|
|
614
|
+
channel.weight ?? ZLINK_DEFAULT_PUBLIC_WEIGHT
|
|
615
|
+
)
|
|
616
|
+
])
|
|
617
|
+
),
|
|
618
|
+
applicationVersion: this.options.registration.applicationVersion
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
|
|
568
622
|
async reconcileAndPublishMeshNodeState(
|
|
569
623
|
state: ZLinkFrameworkRuntimeState,
|
|
570
624
|
meshName: string,
|
|
@@ -578,13 +632,20 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
578
632
|
if (owner === undefined) return;
|
|
579
633
|
const current = (await location.runtime.listLiveMeshNodes(meshName, signal)).find(
|
|
580
634
|
(descriptor) =>
|
|
581
|
-
|
|
635
|
+
routingIdsEqual(descriptor.rid, status.routingId) &&
|
|
582
636
|
descriptor.lifecycleGeneration === status.lifecycleGeneration &&
|
|
583
637
|
descriptor.ownerId === owner.ownerId &&
|
|
584
638
|
descriptor.leaseGeneration === owner.leaseGeneration
|
|
585
639
|
);
|
|
586
640
|
if (current !== undefined) {
|
|
587
|
-
this.publishedMeshNodeDescriptors.set(meshName,
|
|
641
|
+
this.publishedMeshNodeDescriptors.set(meshName, {
|
|
642
|
+
...current,
|
|
643
|
+
...this.localDescriptorFields(
|
|
644
|
+
meshName,
|
|
645
|
+
this.options.registration.spotNodes.get(meshName)!,
|
|
646
|
+
state
|
|
647
|
+
)
|
|
648
|
+
});
|
|
588
649
|
this.descriptorRevisionByMesh.set(
|
|
589
650
|
meshName,
|
|
590
651
|
maxBigInt(this.descriptorRevisionByMesh.get(meshName) ?? 0n, current.descriptorRevision)
|
|
@@ -848,12 +909,16 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
848
909
|
};
|
|
849
910
|
await settle(publishers.map(async (publisher) => publisher.close()));
|
|
850
911
|
await settle(autoConnectLoops.map((loop) => loop.prepareTransportShutdown()));
|
|
851
|
-
await settle(
|
|
852
|
-
|
|
912
|
+
await settle(
|
|
913
|
+
entryActivations
|
|
914
|
+
.reverse()
|
|
915
|
+
.map((activation) => awaitWithAbort(activation.dispose(deadline), signal))
|
|
916
|
+
);
|
|
917
|
+
await settle(meshPumps.reverse().map((pump) => pump.dispose(signal)));
|
|
853
918
|
await settle(
|
|
854
919
|
meshNodes.reverse().map(async (node) => {
|
|
855
|
-
node.shutdown(DEFAULT_SPOT_NODE_SHUTDOWN_TIMEOUT_MS);
|
|
856
|
-
node.close();
|
|
920
|
+
await node.shutdown(DEFAULT_SPOT_NODE_SHUTDOWN_TIMEOUT_MS);
|
|
921
|
+
await node.close();
|
|
857
922
|
})
|
|
858
923
|
);
|
|
859
924
|
for (const completions of meshCompletions) {
|
|
@@ -870,39 +935,61 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
870
935
|
this.meshCompletions.clear();
|
|
871
936
|
}
|
|
872
937
|
|
|
873
|
-
|
|
938
|
+
/**
|
|
939
|
+
* Node and Channel records go straight to the framework dispatcher in the
|
|
940
|
+
* pump's turn. Only Spot and Actor records addressed to the Entry Spot wait
|
|
941
|
+
* for its activation first.
|
|
942
|
+
*/
|
|
943
|
+
private dispatchMeshRecord(
|
|
874
944
|
meshName: string,
|
|
875
945
|
owner: ReadyRecord,
|
|
876
946
|
record: ReceiveRecord
|
|
877
|
-
): Promise<void> {
|
|
878
|
-
const node = this.meshNodes.get(meshName);
|
|
879
|
-
const targetsEntrySpot =
|
|
880
|
-
owner.spotId === null ||
|
|
881
|
-
(node !== undefined &&
|
|
882
|
-
routingIdsEqual(owner.spotId as unknown as RoutingId, String(node.status().routingId)));
|
|
947
|
+
): void | Promise<void> {
|
|
883
948
|
if (
|
|
884
|
-
targetsEntrySpot &&
|
|
885
949
|
(record.kind === ReceiveKind.ActorSend ||
|
|
886
950
|
record.kind === ReceiveKind.ActorRequest ||
|
|
887
951
|
record.kind === ReceiveKind.SpotSend ||
|
|
888
952
|
record.kind === ReceiveKind.SpotRequest ||
|
|
889
|
-
record.kind === ReceiveKind.SpotMulticast)
|
|
953
|
+
record.kind === ReceiveKind.SpotMulticast) &&
|
|
954
|
+
this.targetsEntrySpot(meshName, owner)
|
|
890
955
|
) {
|
|
891
|
-
|
|
956
|
+
return this.ensureEntryActivation(meshName).then(() =>
|
|
957
|
+
this.dispatchFrameworkRecord(meshName, owner, record)
|
|
958
|
+
);
|
|
892
959
|
}
|
|
960
|
+
return this.dispatchFrameworkRecord(meshName, owner, record);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
private targetsEntrySpot(meshName: string, owner: ReadyRecord): boolean {
|
|
964
|
+
if (owner.spotId === null) return true;
|
|
965
|
+
const node = this.meshNodes.get(meshName);
|
|
966
|
+
return (
|
|
967
|
+
node !== undefined &&
|
|
968
|
+
routingIdsEqual(owner.spotId as unknown as RoutingId, String(node.status().routingId))
|
|
969
|
+
);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
private dispatchFrameworkRecord(
|
|
973
|
+
meshName: string,
|
|
974
|
+
owner: ReadyRecord,
|
|
975
|
+
record: ReceiveRecord
|
|
976
|
+
): void | Promise<void> {
|
|
893
977
|
const dispatcher = this.options.meshRecordDispatcher;
|
|
894
978
|
if (dispatcher === undefined) {
|
|
895
|
-
|
|
896
|
-
|
|
979
|
+
return Promise.reject(
|
|
980
|
+
new ZLinkConfigurationException(
|
|
981
|
+
`MeshNode '${meshName}' received a record before its framework dispatcher was registered.`
|
|
982
|
+
)
|
|
897
983
|
);
|
|
898
984
|
}
|
|
899
|
-
|
|
985
|
+
return dispatcher(meshName, owner, record);
|
|
900
986
|
}
|
|
901
987
|
|
|
902
988
|
async dispatchEntrySpotRecord(
|
|
903
989
|
meshName: string,
|
|
904
990
|
owner: ReadyRecord,
|
|
905
|
-
record: ReceiveRecord
|
|
991
|
+
record: ReceiveRecord,
|
|
992
|
+
admit?: ZLinkMeshDispatchAdmission
|
|
906
993
|
): Promise<boolean> {
|
|
907
994
|
if (
|
|
908
995
|
record.kind !== ReceiveKind.SpotSend &&
|
|
@@ -922,11 +1009,13 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
922
1009
|
'MeshNode Entry Spot multicast record is missing its topic.'
|
|
923
1010
|
);
|
|
924
1011
|
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1012
|
+
const dispatch = () =>
|
|
1013
|
+
activation.dispatchSubscriptionRecord(
|
|
1014
|
+
record.topic!,
|
|
1015
|
+
record.parts,
|
|
1016
|
+
record.sourceNodeRid as unknown as RoutingId | null
|
|
1017
|
+
);
|
|
1018
|
+
await (admit === undefined ? dispatch() : admit(dispatch));
|
|
930
1019
|
return true;
|
|
931
1020
|
}
|
|
932
1021
|
const envelope = decodeChannelEnvelope(
|
|
@@ -940,21 +1029,30 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
940
1029
|
channelName: envelope.header.channelName,
|
|
941
1030
|
contentType: envelope.header.contentType
|
|
942
1031
|
};
|
|
943
|
-
if (record.kind === ReceiveKind.SpotSend) {
|
|
944
|
-
await activation.dispatchPacketEncoded(envelope.packetName, decodePayload, context, false);
|
|
945
|
-
return true;
|
|
946
|
-
}
|
|
947
1032
|
try {
|
|
948
|
-
const
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1033
|
+
const dispatch = async () => {
|
|
1034
|
+
if (record.kind === ReceiveKind.SpotSend) {
|
|
1035
|
+
await activation.dispatchPacketEncoded(
|
|
1036
|
+
envelope.packetName,
|
|
1037
|
+
decodePayload,
|
|
1038
|
+
context,
|
|
1039
|
+
false
|
|
1040
|
+
);
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
const response = await activation.dispatchPacketEncoded(
|
|
1044
|
+
envelope.packetName,
|
|
1045
|
+
decodePayload,
|
|
1046
|
+
context,
|
|
1047
|
+
true
|
|
1048
|
+
);
|
|
1049
|
+
requireEntrySpotReply(
|
|
1050
|
+
record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
|
|
1051
|
+
);
|
|
1052
|
+
};
|
|
1053
|
+
await (admit === undefined ? dispatch() : admit(dispatch));
|
|
957
1054
|
} catch (error) {
|
|
1055
|
+
if (record.kind !== ReceiveKind.SpotRequest) throw error;
|
|
958
1056
|
requireEntrySpotReply(record.reply(encodeChannelErrorReplyParts(envelope.header, error)));
|
|
959
1057
|
}
|
|
960
1058
|
return true;
|
|
@@ -1110,6 +1208,20 @@ export class ZLinkSpotNodeRuntimeManager {
|
|
|
1110
1208
|
await activation.commitServiceActorJoin(actor, handoffBacklog);
|
|
1111
1209
|
}
|
|
1112
1210
|
|
|
1211
|
+
admitEntryActorPacketPrefix(
|
|
1212
|
+
meshName: string,
|
|
1213
|
+
actorId: string,
|
|
1214
|
+
records: readonly import('../actors/actor-handoff').ZLinkActorHandoffPrefixRecord[]
|
|
1215
|
+
): import('../actors/actor-handoff').ZLinkActorHandoffPrefixAdmission {
|
|
1216
|
+
const activation = this.entryActivations.get(meshName);
|
|
1217
|
+
if (activation === undefined) {
|
|
1218
|
+
throw new ZLinkConfigurationException(
|
|
1219
|
+
`Entry Spot Actor '${actorId}' has no activation for MeshNode '${meshName}'.`
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1222
|
+
return activation.admitActorPacketPrefix(actorId, records);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1113
1225
|
executeEntryActor<T>(meshName: string, actorId: string, operation: () => Promise<T>): Promise<T> {
|
|
1114
1226
|
const activation = this.entryActivations.get(meshName);
|
|
1115
1227
|
if (activation === undefined) {
|
|
@@ -1345,7 +1457,8 @@ function effectiveObjectRole(registration: ZLinkSpotNodeOptions): ZLinkObjectRol
|
|
|
1345
1457
|
function objectCapability(
|
|
1346
1458
|
objectKind: 'actor' | 'user_spot' | 'instance_spot',
|
|
1347
1459
|
stableType: string,
|
|
1348
|
-
factory: DescriptorFactoryRegistration
|
|
1460
|
+
factory: DescriptorFactoryRegistration,
|
|
1461
|
+
entryAccepted = false
|
|
1349
1462
|
) {
|
|
1350
1463
|
const policy = factory.relocation?.kind ?? 'disabled';
|
|
1351
1464
|
return {
|
|
@@ -1353,10 +1466,27 @@ function objectCapability(
|
|
|
1353
1466
|
stableType,
|
|
1354
1467
|
policy,
|
|
1355
1468
|
hasSnapshotAdapter: policy === 'snapshot',
|
|
1356
|
-
limit: objectKind === 'actor' ? 0 : (factory.options?.stableTypeLimit ?? 0)
|
|
1469
|
+
limit: objectKind === 'actor' ? 0 : (factory.options?.stableTypeLimit ?? 0),
|
|
1470
|
+
entryAccepted
|
|
1357
1471
|
};
|
|
1358
1472
|
}
|
|
1359
1473
|
|
|
1474
|
+
/**
|
|
1475
|
+
* The one decision for creating a new Actor on this node (Actor model §6.3): the node registered
|
|
1476
|
+
* an Entry Spot type that accepts the Actor type and an Actor factory for it. Publication and the
|
|
1477
|
+
* target refusal both read it.
|
|
1478
|
+
*/
|
|
1479
|
+
export function registrationAcceptsNewActor(
|
|
1480
|
+
registration: ZLinkSpotNodeOptions,
|
|
1481
|
+
stableType: string
|
|
1482
|
+
): boolean {
|
|
1483
|
+
return (
|
|
1484
|
+
registration.entrySpotType !== undefined &&
|
|
1485
|
+
registration.entrySpotActorType === stableType &&
|
|
1486
|
+
effectiveActorRegistrations(registration).some(([type]) => type === stableType)
|
|
1487
|
+
);
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1360
1490
|
function aggregatePlacementCapacity(actorLimit: number, spotLimit: number): number {
|
|
1361
1491
|
const unlimited = ZLINK_MAX_CAPACITY;
|
|
1362
1492
|
const actors = actorLimit === 0 ? unlimited : actorLimit;
|
|
@@ -370,7 +370,7 @@ function createAddressedSpotRequestCall(
|
|
|
370
370
|
markSubmitted(options);
|
|
371
371
|
rejectSameSpotAsyncRequest(serial, spotId, 'yield');
|
|
372
372
|
const pending = begin<TReply>(signal);
|
|
373
|
-
return turn.
|
|
373
|
+
return turn.yieldFrameworkPromise(pending);
|
|
374
374
|
}
|
|
375
375
|
};
|
|
376
376
|
}
|
|
@@ -508,7 +508,7 @@ function wrapRequestCall(
|
|
|
508
508
|
yield<TReply>(signal?: AbortSignal) {
|
|
509
509
|
const turn = requireZLinkYieldTurn();
|
|
510
510
|
const pending = begin<TReply>(signal);
|
|
511
|
-
return turn.
|
|
511
|
+
return turn.yieldFrameworkPromise(pending);
|
|
512
512
|
}
|
|
513
513
|
};
|
|
514
514
|
}
|
|
@@ -626,7 +626,7 @@ function wrapRoutedSpotRequestCall(
|
|
|
626
626
|
const turn = requireZLinkYieldTurn();
|
|
627
627
|
rejectSameSpotAsyncRequest(serial, spot.spotId, 'yield');
|
|
628
628
|
const pending = begin<TReply>(signal);
|
|
629
|
-
return turn.
|
|
629
|
+
return turn.yieldFrameworkPromise(pending);
|
|
630
630
|
}
|
|
631
631
|
};
|
|
632
632
|
}
|
|
@@ -8,7 +8,7 @@ import type { Message } from '../../contracts/Common/Message';
|
|
|
8
8
|
import { ZLinkBufferMessage as RuntimeMessage } from '../backend/runtime-message';
|
|
9
9
|
import type { ZLinkBackendReceived as BackendReceived } from '../backend/runtime-values';
|
|
10
10
|
import { decodeChannelEnvelope } from '../channels/channel-envelope';
|
|
11
|
-
import { decodeRoutingId as decodeWireRoutingId } from '../routing-id';
|
|
11
|
+
import { decodeRoutingId as decodeWireRoutingId, routingIdsEqual } from '../routing-id';
|
|
12
12
|
import {
|
|
13
13
|
REMOTE_ACTOR_JOIN_PACKET,
|
|
14
14
|
type ZLinkRemoteActorJoinWirePayload
|
|
@@ -176,7 +176,14 @@ export function decodeHandoffBacklog(value: unknown): readonly ZLinkActorHandoff
|
|
|
176
176
|
BigInt(source.ownerLeaseGeneration) <= 0n ||
|
|
177
177
|
source.nodeRid.length === 0 ||
|
|
178
178
|
BigInt(source.nodeGeneration) <= 0n ||
|
|
179
|
-
source.replyRouteId !==
|
|
179
|
+
source.replyRouteId !==
|
|
180
|
+
(packet.messageFollowOrigin !== undefined &&
|
|
181
|
+
routingIdsEqual(
|
|
182
|
+
decodeWireRoutingId(source.nodeRid, source.nodeRidHex),
|
|
183
|
+
packet.messageFollowOrigin.sourceNodeRid
|
|
184
|
+
)
|
|
185
|
+
? packet.messageFollowOrigin.originalReplyRouteId.toString()
|
|
186
|
+
: messageFollowContext.replyRouteId))) ||
|
|
180
187
|
(!packet.returnResponse && source !== undefined)
|
|
181
188
|
) {
|
|
182
189
|
throw new Error('Remote actor handoff request source fence is invalid.');
|
|
@@ -92,7 +92,6 @@ export interface ZLinkSpotActorTransferRuntime {
|
|
|
92
92
|
commitRoutedActor(actor: ZLinkActor, spotId: RoutingId, spot: ZLinkSpot): void;
|
|
93
93
|
clearRoutedActor(actor: ZLinkActor): void;
|
|
94
94
|
rollbackRoutedActor(actor: ZLinkActor, signal?: AbortSignal): Promise<void>;
|
|
95
|
-
notifyCoreSourceLeave(actor: ZLinkActor, callback: () => Promise<void>): Promise<void>;
|
|
96
95
|
actorEntryNodeRid(actor: ZLinkActor): RoutingId | undefined;
|
|
97
96
|
}
|
|
98
97
|
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import { ZLinkUserSpotExecutionMode } from '../../contracts';
|
|
2
2
|
import { ZLinkActorSerialExecutor } from '../actors';
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
ZLinkActorHandoffDispatch,
|
|
5
|
+
ZLinkActorHandoffPrefixAdmission,
|
|
6
|
+
ZLinkActorHandoffPrefixRecord
|
|
7
|
+
} from '../actors/actor-handoff';
|
|
8
|
+
import type { ZLinkExecutionBarrier, ZLinkExecutionBarrierSeal } from '../execution';
|
|
4
9
|
import type {
|
|
5
10
|
ZLinkSerialSchedulerOptions,
|
|
6
|
-
ZLinkSerialWorkPreparation,
|
|
7
11
|
ZLinkSerialWorkOptions
|
|
8
12
|
} from '../execution/serial-execution-queue';
|
|
9
13
|
import { ZLinkSpotSerialTurnExecutor } from './spot-serial-turn-executor';
|
|
10
14
|
|
|
15
|
+
export type ZLinkSpotPreparationCompletion = 'publication' | 'first-terminal';
|
|
16
|
+
|
|
17
|
+
export type ZLinkActorPacketTurnDispatch = (
|
|
18
|
+
serial: ZLinkSpotSerialTurnExecutor,
|
|
19
|
+
...args: Parameters<ZLinkActorHandoffDispatch>
|
|
20
|
+
) => ReturnType<ZLinkActorHandoffDispatch>;
|
|
21
|
+
|
|
11
22
|
/**
|
|
12
23
|
* Owns every application serial unit that belongs to one Spot activation.
|
|
13
24
|
*
|
|
@@ -21,6 +32,11 @@ export class ZLinkSpotSerialExecutor {
|
|
|
21
32
|
private executionBarrier: ZLinkExecutionBarrier | undefined;
|
|
22
33
|
private closing = false;
|
|
23
34
|
private closePromise: Promise<void> | undefined;
|
|
35
|
+
private preparation?: {
|
|
36
|
+
readonly seal: ZLinkExecutionBarrierSeal;
|
|
37
|
+
readonly complete: (terminal?: () => Promise<void>) => void;
|
|
38
|
+
readonly execution: Promise<void>;
|
|
39
|
+
};
|
|
24
40
|
|
|
25
41
|
constructor(
|
|
26
42
|
private readonly spotSerial: ZLinkSpotSerialTurnExecutor,
|
|
@@ -39,6 +55,54 @@ export class ZLinkSpotSerialExecutor {
|
|
|
39
55
|
for (const serial of this.timerSerials.values()) serial.setExecutionBarrier(barrier);
|
|
40
56
|
}
|
|
41
57
|
|
|
58
|
+
get isPreparing(): boolean {
|
|
59
|
+
return this.preparation !== undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
beginPreparation(kind: 'activation' | 'relocation' = 'activation'): void {
|
|
63
|
+
if (this.preparation !== undefined || this.executionBarrier === undefined)
|
|
64
|
+
throw new Error('Activation preparation requires one unowned execution barrier.');
|
|
65
|
+
const barrier = this.executionBarrier;
|
|
66
|
+
const seal = barrier.seal(kind);
|
|
67
|
+
let complete!: (terminal?: () => Promise<void>) => void;
|
|
68
|
+
const terminal = new Promise<(() => Promise<void>) | undefined>((resolve) => {
|
|
69
|
+
complete = resolve;
|
|
70
|
+
});
|
|
71
|
+
// The staging seal itself owns target preparation. No normal preparation
|
|
72
|
+
// item is admitted in addition to this lifecycle owner.
|
|
73
|
+
const execution = this.spotSerial.executeControlLifecycleOperation(
|
|
74
|
+
async () => {
|
|
75
|
+
const finish = await terminal;
|
|
76
|
+
await finish?.();
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
canExecuteApplication: (record) => record.context === undefined || !barrier.isCurrent(seal)
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
this.preparation = { seal, complete, execution };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
openPreparationAdmission(): void {
|
|
86
|
+
if (this.preparation !== undefined) this.executionBarrier!.abort(this.preparation.seal);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async finishPreparation(terminal?: () => Promise<void>): Promise<void> {
|
|
90
|
+
const preparation = this.preparation;
|
|
91
|
+
if (preparation === undefined) {
|
|
92
|
+
await terminal?.();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
preparation.complete(terminal);
|
|
96
|
+
try {
|
|
97
|
+
await preparation.execution;
|
|
98
|
+
} finally {
|
|
99
|
+
if (this.preparation === preparation) {
|
|
100
|
+
this.executionBarrier!.abort(preparation.seal);
|
|
101
|
+
this.preparation = undefined;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
42
106
|
executeSpot<T>(
|
|
43
107
|
operation: () => Promise<T> | T,
|
|
44
108
|
workOptions?: ZLinkSerialWorkOptions
|
|
@@ -55,35 +119,43 @@ export class ZLinkSpotSerialExecutor {
|
|
|
55
119
|
return this.actorExecutor(actorId).execute(() => operation(serial), workOptions);
|
|
56
120
|
}
|
|
57
121
|
|
|
58
|
-
|
|
59
|
-
|
|
122
|
+
executeTimer<T>(
|
|
123
|
+
timerName: string,
|
|
124
|
+
operation: () => Promise<T> | T,
|
|
125
|
+
workOptions?: ZLinkSerialWorkOptions
|
|
126
|
+
): Promise<T> {
|
|
127
|
+
return this.timerSerial(timerName).post(operation, workOptions);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Admits held packets through the same Actor FIFO as ordinary ingress. */
|
|
131
|
+
admitActorPacketPrefix(
|
|
60
132
|
actorId: string,
|
|
61
|
-
records: readonly
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
child: (serial: ZLinkSpotSerialTurnExecutor) => Promise<TChild> | TChild
|
|
65
|
-
) => Promise<TChild>
|
|
66
|
-
) => Promise<void>;
|
|
67
|
-
readonly preparation?: ZLinkSerialWorkPreparation;
|
|
68
|
-
readonly workOptions?: ZLinkSerialWorkOptions;
|
|
69
|
-
}[]
|
|
70
|
-
): readonly Promise<void>[] {
|
|
133
|
+
records: readonly ZLinkActorHandoffPrefixRecord[],
|
|
134
|
+
dispatch: ZLinkActorPacketTurnDispatch
|
|
135
|
+
): ZLinkActorHandoffPrefixAdmission {
|
|
71
136
|
const serial = this.actorSerial(actorId);
|
|
72
|
-
|
|
137
|
+
const terminals = this.actorExecutor(actorId).admitDurablePrefix(
|
|
73
138
|
records.map((record) => ({
|
|
74
|
-
operation: (executeChild) =>
|
|
139
|
+
operation: (executeChild) =>
|
|
140
|
+
record.drain((parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef) =>
|
|
141
|
+
executeChild(() =>
|
|
142
|
+
dispatch(serial, parts, returnResponse, remoteBoundSessionTarget, fallbackActorRef)
|
|
143
|
+
)
|
|
144
|
+
),
|
|
75
145
|
preparation: record.preparation,
|
|
76
|
-
workOptions: record.
|
|
146
|
+
workOptions: { payloadBytes: record.payloadBytes, onWithdrawable: record.onWithdrawable }
|
|
77
147
|
}))
|
|
78
148
|
);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
149
|
+
const terminal = Promise.allSettled(terminals).then((outcomes) => {
|
|
150
|
+
const errors = outcomes.flatMap((outcome) =>
|
|
151
|
+
outcome.status === 'rejected' ? [outcome.reason] : []
|
|
152
|
+
);
|
|
153
|
+
if (errors.length === 1) throw errors[0];
|
|
154
|
+
if (errors.length > 1) {
|
|
155
|
+
throw new AggregateError(errors, `Actor '${actorId}' durable prefix replay failed.`);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
return { terminal };
|
|
87
159
|
}
|
|
88
160
|
|
|
89
161
|
isTimerExecuting(timerName: string): boolean {
|