@zlink-systems/framework 0.30.0 → 0.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +150 -68
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
- package/dist/contracts/Channels/Calls.d.ts +2 -1
- package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
- package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
- package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
- package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
- package/dist/contracts/Common/encoded-payload-storage.js +5 -2
- package/dist/contracts/Configuration/Builders.d.ts +1 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
- package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
- package/dist/contracts/Handlers/Attributes.d.ts +5 -13
- package/dist/contracts/Handlers/Attributes.js +7 -11
- package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
- package/dist/contracts/Handlers/JsonContract.js +4 -153
- package/dist/contracts/Locations/Rows.d.ts +2 -0
- package/dist/contracts/Spots/Contracts.d.ts +6 -1
- package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
- package/dist/nest-integration.d.ts +1 -1
- package/dist/nest-integration.js +2 -1
- package/dist/runtime/abort.d.ts +5 -0
- package/dist/runtime/abort.js +10 -0
- package/dist/runtime/actors/actor-authority-publication.js +3 -2
- package/dist/runtime/actors/actor-client.d.ts +1 -2
- package/dist/runtime/actors/actor-client.js +52 -57
- package/dist/runtime/actors/actor-context.d.ts +2 -0
- package/dist/runtime/actors/actor-context.js +46 -9
- package/dist/runtime/actors/actor-handoff.d.ts +8 -4
- package/dist/runtime/actors/actor-handoff.js +219 -92
- package/dist/runtime/actors/actor-join-relocation.d.ts +3 -0
- package/dist/runtime/actors/actor-local-native-join.js +13 -12
- package/dist/runtime/actors/actor-mailbox.js +27 -1
- package/dist/runtime/actors/actor-remote-joiner.js +3 -1
- package/dist/runtime/actors/actor-remote-wire.js +15 -0
- package/dist/runtime/actors/actor-reply.d.ts +4 -0
- package/dist/runtime/actors/actor-reply.js +29 -0
- package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
- package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
- package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
- package/dist/runtime/actors/actor-runtime-state.js +2 -20
- package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
- package/dist/runtime/actors/index.d.ts +8 -3
- package/dist/runtime/actors/index.js +55 -27
- package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
- package/dist/runtime/actors/session-disconnected-wire.js +48 -0
- package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
- package/dist/runtime/admission.d.ts +9 -1
- package/dist/runtime/admission.js +56 -23
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +6 -8
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +39 -22
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +15 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +61 -20
- package/dist/runtime/application-jobs/contracts.d.ts +12 -1
- package/dist/runtime/backend/contracts/index.d.ts +37 -12
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
- package/dist/runtime/backend/mesh-completion-table.d.ts +9 -1
- package/dist/runtime/backend/mesh-completion-table.js +154 -49
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +28 -1
- package/dist/runtime/backend/mesh-dispatch-pump.js +208 -101
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
- package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -9
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
- package/dist/runtime/backend/node/node-raw-binding-port.js +124 -72
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +46 -13
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +181 -164
- package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +11 -11
- package/dist/runtime/backend/raw-binding-port.d.ts +2 -2
- package/dist/runtime/backend/runtime-message.d.ts +1 -0
- package/dist/runtime/backend/runtime-message.js +5 -0
- package/dist/runtime/backend/runtime-values.d.ts +1 -0
- package/dist/runtime/backend/runtime-values.js +2 -1
- package/dist/runtime/channels/channel-clients.d.ts +2 -0
- package/dist/runtime/channels/channel-clients.js +75 -23
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +25 -5
- package/dist/runtime/channels/channel-dispatch-pipeline.js +111 -56
- package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
- package/dist/runtime/channels/channel-dispatch-services.js +45 -0
- package/dist/runtime/channels/channel-dispatchers.d.ts +4 -3
- package/dist/runtime/channels/channel-dispatchers.js +62 -54
- package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
- package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
- package/dist/runtime/channels/channel-envelope.d.ts +2 -0
- package/dist/runtime/channels/channel-envelope.js +146 -28
- package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
- package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
- package/dist/runtime/channels/channel-runtime-manager.d.ts +9 -8
- package/dist/runtime/channels/channel-runtime-manager.js +16 -16
- package/dist/runtime/channels/channel-transports.d.ts +18 -16
- package/dist/runtime/channels/channel-transports.js +77 -58
- package/dist/runtime/channels/client-server-location-runtime.js +5 -4
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/fanout-location-runtime.js +3 -3
- package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
- package/dist/runtime/channels/local-spot-route-transport.js +2 -1
- package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
- package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
- package/dist/runtime/channels/source-spot-router.d.ts +2 -2
- package/dist/runtime/channels/source-spot-router.js +4 -4
- package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
- package/dist/runtime/channels/spot-node-route-transport.js +4 -4
- package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
- package/dist/runtime/diagnostics/flow-context.js +19 -7
- package/dist/runtime/diagnostics/index.js +4 -9
- package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
- package/dist/runtime/diagnostics/message-flow.js +35 -5
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
- package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
- package/dist/runtime/execution/index.d.ts +4 -2
- package/dist/runtime/execution/index.js +33 -10
- package/dist/runtime/execution/serial-execution-queue.d.ts +5 -0
- package/dist/runtime/execution/serial-execution-queue.js +22 -2
- package/dist/runtime/execution/state-lane.d.ts +2 -0
- package/dist/runtime/execution/state-lane.js +5 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
- package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
- package/dist/runtime/foundation/durable-service-request.js +98 -0
- package/dist/runtime/foundation/operation-identity.d.ts +1 -0
- package/dist/runtime/foundation/operation-identity.js +5 -1
- package/dist/runtime/foundation/operation-registry.d.ts +25 -1
- package/dist/runtime/foundation/operation-registry.js +86 -18
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +61 -8
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +486 -266
- package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
- package/dist/runtime/foundation/service-liveness-registry.js +38 -0
- package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
- package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +3 -3
- package/dist/runtime/foundation/service-relocation-object-owner.js +48 -34
- package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
- package/dist/runtime/foundation/service-relocation-runtime.js +20 -4
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +10 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
- package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
- package/dist/runtime/foundation/service-stateful-registry.js +24 -26
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +75 -9
- package/dist/runtime/foundation/service-stateful-runtime.js +486 -218
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -6
- package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
- package/dist/runtime/foundation/service-topology-registry.d.ts +12 -2
- package/dist/runtime/foundation/service-topology-registry.js +61 -27
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
- package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +13 -3
- package/dist/runtime/foundation/service-wire-m6a-codec.js +189 -78
- package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
- package/dist/runtime/handlers/handler-instance-scope.js +54 -11
- package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
- package/dist/runtime/host/actor-packet-relay.js +59 -72
- package/dist/runtime/host/actor-placement-coordinator.js +25 -8
- package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
- package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
- package/dist/runtime/host/actor-transfer-runtime.js +85 -331
- package/dist/runtime/host/application-job-queue.d.ts +40 -7
- package/dist/runtime/host/application-job-queue.js +137 -42
- package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
- package/dist/runtime/host/entry-actor-runtime.js +3 -0
- package/dist/runtime/host/index.d.ts +12 -2
- package/dist/runtime/host/index.js +300 -202
- package/dist/runtime/host/location-runtime-owner.js +2 -6
- package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
- package/dist/runtime/host/mesh-router-resolver.js +14 -6
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
- package/dist/runtime/host/remote-bound-session-relay.js +73 -208
- package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
- package/dist/runtime/host/route-mesh-runtime.js +6 -4
- package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
- package/dist/runtime/host/runtime-shutdown.js +3 -2
- package/dist/runtime/host/service-relocation-control.d.ts +1 -0
- package/dist/runtime/host/service-relocation-control.js +10 -4
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +22 -14
- package/dist/runtime/host/service-relocation-host-runtime.js +754 -599
- package/dist/runtime/host/spot-address-transport.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.js +16 -7
- package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
- package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
- package/dist/runtime/locations/actor-location-claims.js +34 -19
- package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
- package/dist/runtime/locations/auto-connect-loop.js +22 -14
- package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
- package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
- package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
- package/dist/runtime/locations/descriptor-publication.js +11 -0
- package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
- package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
- package/dist/runtime/locations/in-memory-authority-store.js +56 -19
- package/dist/runtime/locations/in-memory-location-store.js +1 -10
- package/dist/runtime/locations/index.d.ts +1 -0
- package/dist/runtime/locations/index.js +1 -0
- package/dist/runtime/locations/lease-tracker.js +1 -6
- package/dist/runtime/locations/lifecycle.d.ts +1 -2
- package/dist/runtime/locations/lifecycle.js +2 -5
- package/dist/runtime/locations/location-store-repository.d.ts +51 -1
- package/dist/runtime/locations/location-store-repository.js +363 -139
- package/dist/runtime/locations/relocation-blob.d.ts +18 -1
- package/dist/runtime/locations/relocation-blob.js +52 -1
- package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
- package/dist/runtime/locations/request-source-resolver.js +80 -0
- package/dist/runtime/locations/resolvers.js +1 -1
- package/dist/runtime/locations/runtime.d.ts +7 -3
- package/dist/runtime/locations/runtime.js +61 -53
- package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
- package/dist/runtime/messaging/framework-json-v1.js +38 -294
- package/dist/runtime/messaging/packet-name.d.ts +1 -1
- package/dist/runtime/messaging/packet-name.js +8 -24
- package/dist/runtime/messaging/payload-codec.d.ts +7 -1
- package/dist/runtime/messaging/payload-codec.js +7 -6
- package/dist/runtime/messaging/request-result.d.ts +2 -0
- package/dist/runtime/messaging/request-result.js +57 -0
- package/dist/runtime/messaging/submission-result.d.ts +1 -0
- package/dist/runtime/messaging/submission-result.js +5 -2
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +34 -1
- package/dist/runtime/protocol/service_wire_codec.generated.js +229 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +16 -1
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +37 -8
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +7 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +36 -21
- package/dist/runtime/spots/index.d.ts +21 -11
- package/dist/runtime/spots/index.js +243 -178
- package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
- package/dist/runtime/spots/spot-activation-registry.js +21 -11
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +7 -7
- package/dist/runtime/spots/spot-activation.d.ts +7 -3
- package/dist/runtime/spots/spot-activation.js +140 -52
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
- package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-membership.js +0 -8
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
- package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
- package/dist/runtime/spots/spot-entry-activation.js +20 -11
- package/dist/runtime/spots/spot-handler-registry.d.ts +7 -4
- package/dist/runtime/spots/spot-handler-registry.js +24 -10
- package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
- package/dist/runtime/spots/spot-manager-public.js +2 -2
- package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
- package/dist/runtime/spots/spot-node-autoconnect.js +22 -42
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
- package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
- package/dist/runtime/spots/spot-outbound.d.ts +3 -0
- package/dist/runtime/spots/spot-outbound.js +27 -18
- package/dist/runtime/spots/spot-remote-codec.js +5 -1
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +1 -1
- package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
- package/dist/runtime/spots/spot-serial-executor.js +61 -8
- package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
- package/dist/runtime/spots/spot-subscription-dispatch.js +1 -4
- package/dist/runtime/spots/spot-timer.d.ts +57 -5
- package/dist/runtime/spots/spot-timer.js +288 -103
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
- package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
- package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
- package/dist/runtime/streams/bound-session-service.d.ts +1 -1
- package/dist/runtime/streams/bound-session-service.js +6 -11
- package/dist/runtime/streams/index.d.ts +3 -2
- package/dist/runtime/streams/index.js +6 -4
- package/dist/runtime/streams/managed-stream.js +3 -2
- package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
- package/dist/runtime/streams/session-actor-coordinator.js +15 -32
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
- package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
- package/dist/runtime/streams/stream-session-runtime.js +14 -31
- package/dist/runtime/workers/index.js +1 -1
- package/package.json +3 -3
- package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
- package/src/contracts/Channels/Calls.ts +2 -1
- package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
- package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
- package/src/contracts/Common/encoded-payload-storage.ts +6 -3
- package/src/contracts/Configuration/Builders.ts +4 -1
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
- package/src/contracts/Handlers/Attributes.ts +14 -21
- package/src/contracts/Handlers/JsonContract.ts +8 -216
- package/src/contracts/Locations/Rows.ts +2 -0
- package/src/contracts/Spots/Contracts.ts +10 -1
- package/src/contracts/Spots/ZLinkSpot.ts +3 -3
- package/src/nest-integration.ts +1 -0
- package/src/runtime/abort.ts +12 -0
- package/src/runtime/actors/actor-authority-publication.ts +3 -2
- package/src/runtime/actors/actor-client.ts +100 -85
- package/src/runtime/actors/actor-context.ts +49 -9
- package/src/runtime/actors/actor-handoff.ts +291 -110
- package/src/runtime/actors/actor-join-relocation.ts +3 -0
- package/src/runtime/actors/actor-local-native-join.ts +21 -26
- package/src/runtime/actors/actor-mailbox.ts +40 -2
- package/src/runtime/actors/actor-remote-joiner.ts +6 -1
- package/src/runtime/actors/actor-remote-wire.ts +17 -0
- package/src/runtime/actors/actor-reply.ts +42 -0
- package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
- package/src/runtime/actors/actor-routed-json-request.ts +10 -2
- package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
- package/src/runtime/actors/actor-runtime-state.ts +2 -20
- package/src/runtime/actors/actor-source-transfer.ts +1 -34
- package/src/runtime/actors/index.ts +60 -32
- package/src/runtime/actors/session-disconnected-wire.ts +66 -0
- package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
- package/src/runtime/admission.ts +69 -21
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +41 -25
- package/src/runtime/application-jobs/application-job-queue-scope.ts +83 -22
- package/src/runtime/application-jobs/contracts.ts +16 -1
- package/src/runtime/backend/contracts/index.ts +92 -18
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
- package/src/runtime/backend/mesh-completion-table.ts +160 -57
- package/src/runtime/backend/mesh-dispatch-pump.ts +237 -108
- package/src/runtime/backend/node/node-backend-adapter-support.ts +17 -8
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
- package/src/runtime/backend/node/node-raw-binding-port.ts +148 -85
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +315 -201
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +26 -11
- package/src/runtime/backend/raw-binding-port.ts +7 -2
- package/src/runtime/backend/runtime-message.ts +6 -0
- package/src/runtime/backend/runtime-values.ts +1 -0
- package/src/runtime/channels/channel-clients.ts +132 -58
- package/src/runtime/channels/channel-dispatch-pipeline.ts +198 -114
- package/src/runtime/channels/channel-dispatch-services.ts +69 -1
- package/src/runtime/channels/channel-dispatchers.ts +136 -90
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
- package/src/runtime/channels/channel-envelope.ts +225 -31
- package/src/runtime/channels/channel-outbound-operations.ts +22 -8
- package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
- package/src/runtime/channels/channel-runtime-manager.ts +41 -17
- package/src/runtime/channels/channel-transports.ts +171 -112
- package/src/runtime/channels/client-server-location-runtime.ts +11 -10
- package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
- package/src/runtime/channels/fanout-location-runtime.ts +17 -9
- package/src/runtime/channels/local-spot-route-transport.ts +3 -1
- package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
- package/src/runtime/channels/source-spot-router.ts +8 -4
- package/src/runtime/channels/spot-node-route-transport.ts +8 -4
- package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
- package/src/runtime/diagnostics/flow-context.ts +20 -7
- package/src/runtime/diagnostics/index.ts +1 -7
- package/src/runtime/diagnostics/message-flow.ts +47 -9
- package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
- package/src/runtime/execution/index.ts +40 -14
- package/src/runtime/execution/serial-execution-queue.ts +33 -4
- package/src/runtime/execution/state-lane.ts +7 -0
- package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
- package/src/runtime/foundation/durable-service-request.ts +137 -0
- package/src/runtime/foundation/operation-identity.ts +5 -1
- package/src/runtime/foundation/operation-registry.ts +98 -20
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +704 -336
- package/src/runtime/foundation/service-liveness-registry.ts +39 -0
- package/src/runtime/foundation/service-mailbox.ts +8 -0
- package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
- package/src/runtime/foundation/service-relocation-object-owner.ts +55 -36
- package/src/runtime/foundation/service-relocation-runtime.ts +25 -4
- package/src/runtime/foundation/service-runtime-contracts.ts +19 -2
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
- package/src/runtime/foundation/service-stateful-registry.ts +38 -35
- package/src/runtime/foundation/service-stateful-runtime.ts +732 -275
- package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -16
- package/src/runtime/foundation/service-topology-registry.ts +91 -36
- package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +231 -76
- package/src/runtime/handlers/handler-instance-scope.ts +67 -16
- package/src/runtime/host/actor-packet-relay.ts +113 -94
- package/src/runtime/host/actor-placement-coordinator.ts +31 -8
- package/src/runtime/host/actor-runtime-options-factory.ts +13 -2
- package/src/runtime/host/actor-transfer-runtime.ts +104 -430
- package/src/runtime/host/application-job-queue.ts +160 -41
- package/src/runtime/host/entry-actor-runtime.ts +4 -0
- package/src/runtime/host/index.ts +473 -271
- package/src/runtime/host/location-runtime-owner.ts +2 -6
- package/src/runtime/host/mesh-router-resolver.ts +13 -5
- package/src/runtime/host/remote-bound-session-relay.ts +88 -271
- package/src/runtime/host/route-mesh-runtime.ts +12 -6
- package/src/runtime/host/runtime-shutdown.ts +15 -4
- package/src/runtime/host/service-relocation-control.ts +11 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +1092 -759
- package/src/runtime/host/spot-address-transport.ts +4 -2
- package/src/runtime/host/spot-runtime-options-factory.ts +20 -7
- package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
- package/src/runtime/locations/actor-location-claims.ts +52 -30
- package/src/runtime/locations/auto-connect-loop.ts +22 -14
- package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
- package/src/runtime/locations/auto-connect-types.ts +0 -1
- package/src/runtime/locations/descriptor-publication.ts +7 -0
- package/src/runtime/locations/domain-store-contract.ts +5 -0
- package/src/runtime/locations/in-memory-authority-store.ts +85 -23
- package/src/runtime/locations/in-memory-location-store.ts +1 -12
- package/src/runtime/locations/index.ts +1 -0
- package/src/runtime/locations/lease-tracker.ts +2 -9
- package/src/runtime/locations/lifecycle.ts +8 -26
- package/src/runtime/locations/location-store-repository.ts +628 -152
- package/src/runtime/locations/relocation-blob.ts +75 -1
- package/src/runtime/locations/request-source-resolver.ts +138 -0
- package/src/runtime/locations/resolvers.ts +2 -2
- package/src/runtime/locations/runtime.ts +98 -64
- package/src/runtime/messaging/framework-json-v1.ts +5 -325
- package/src/runtime/messaging/packet-name.ts +5 -25
- package/src/runtime/messaging/payload-codec.ts +8 -11
- package/src/runtime/messaging/request-result.ts +62 -0
- package/src/runtime/messaging/submission-result.ts +5 -1
- package/src/runtime/protocol/service_wire_codec.generated.ts +218 -5
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +16 -13
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +46 -25
- package/src/runtime/spots/index.ts +389 -283
- package/src/runtime/spots/spot-activation-registry.ts +25 -13
- package/src/runtime/spots/spot-activation-state.ts +12 -19
- package/src/runtime/spots/spot-activation.ts +198 -96
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
- package/src/runtime/spots/spot-actor-membership.ts +0 -15
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
- package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
- package/src/runtime/spots/spot-entry-activation.ts +33 -21
- package/src/runtime/spots/spot-handler-registry.ts +56 -12
- package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
- package/src/runtime/spots/spot-manager-public.ts +2 -2
- package/src/runtime/spots/spot-node-autoconnect.ts +28 -47
- package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
- package/src/runtime/spots/spot-outbound.ts +39 -19
- package/src/runtime/spots/spot-remote-codec.ts +9 -2
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
- package/src/runtime/spots/spot-runtime-ports.ts +1 -1
- package/src/runtime/spots/spot-serial-executor.ts +97 -25
- package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
- package/src/runtime/spots/spot-subscription-dispatch.ts +1 -4
- package/src/runtime/spots/spot-timer.ts +418 -158
- package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
- package/src/runtime/streams/bound-session-service.ts +7 -10
- package/src/runtime/streams/index.ts +12 -6
- package/src/runtime/streams/managed-stream.ts +4 -2
- package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
- package/src/runtime/streams/session-actor-coordinator.ts +39 -88
- package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
- package/src/runtime/streams/stream-session-runtime.ts +13 -34
- package/src/runtime/workers/index.ts +1 -1
|
@@ -18,14 +18,18 @@ import type {
|
|
|
18
18
|
import { ZLinkTimerOverrunPolicy } from '../../contracts';
|
|
19
19
|
import { validateTimerRegistration } from '../../contracts/Configuration/TimerRegistrationValidator';
|
|
20
20
|
import { throwIfAborted } from '../abort';
|
|
21
|
+
import {
|
|
22
|
+
ZLinkFrameworkInternalErrorKind,
|
|
23
|
+
createInternalFrameworkException
|
|
24
|
+
} from '../framework-errors-internal';
|
|
21
25
|
import { ZLinkSpotSerialTurnExecutor } from './spot-serial-turn-executor';
|
|
22
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
prepareHandlerInstance,
|
|
28
|
+
resolveLifecycleHandler
|
|
29
|
+
} from '../handlers/handler-instance-scope';
|
|
23
30
|
import { createInboundFlow, runWithFlow } from '../diagnostics/flow-context';
|
|
24
31
|
import type { ZLinkExecutionBarrier } from '../execution';
|
|
25
|
-
import { ZLinkStateLane } from '../execution/state-lane';
|
|
26
|
-
import { AsyncResource } from 'node:async_hooks';
|
|
27
|
-
|
|
28
|
-
const detachedTimerStateLaneResource = new AsyncResource('zlink:spot-timer');
|
|
32
|
+
import { startOutsideStateLane, ZLinkStateLane } from '../execution/state-lane';
|
|
29
33
|
|
|
30
34
|
export interface ZLinkTimerClock {
|
|
31
35
|
now(): number;
|
|
@@ -51,7 +55,7 @@ interface ZLinkTimerFinalization {
|
|
|
51
55
|
|
|
52
56
|
interface ZLinkTimerFinalizationStart {
|
|
53
57
|
readonly timeout: unknown;
|
|
54
|
-
readonly running: Promise<void
|
|
58
|
+
readonly running: Promise<void> | undefined;
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
type ZLinkTimerFailureReporter = (
|
|
@@ -75,6 +79,13 @@ export interface ZLinkTimerRelocationState {
|
|
|
75
79
|
readonly pendingTicks: readonly ZLinkTimerRelocationPendingTick[];
|
|
76
80
|
}
|
|
77
81
|
|
|
82
|
+
export interface ZLinkManagedTimerStart {
|
|
83
|
+
/** Created paused; the owner starts it with `resume()`. */
|
|
84
|
+
readonly paused?: boolean;
|
|
85
|
+
/** Relocated logical schedule the timer continues from. */
|
|
86
|
+
readonly cursor?: ZLinkTimerRelocationState;
|
|
87
|
+
}
|
|
88
|
+
|
|
78
89
|
export interface ZLinkTimerRelocationPendingTick {
|
|
79
90
|
readonly deliveryIndex: bigint;
|
|
80
91
|
readonly scheduledIndex: bigint;
|
|
@@ -82,18 +93,56 @@ export interface ZLinkTimerRelocationPendingTick {
|
|
|
82
93
|
readonly skippedTicks: bigint;
|
|
83
94
|
}
|
|
84
95
|
|
|
96
|
+
interface ZLinkTimerBinding {
|
|
97
|
+
readonly handler: ZLinkSpotTimerHandler<ZLinkTimerOwnerSpot>;
|
|
98
|
+
readonly spot: ZLinkTimerOwnerSpot;
|
|
99
|
+
readonly executionSerial?: ZLinkSpotSerialTurnExecutor;
|
|
100
|
+
readonly reportFailure?: ZLinkTimerFailureReporter;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface ZLinkTimerBindingSlot {
|
|
104
|
+
binding: ZLinkTimerBinding | undefined;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface ZLinkTimerEntry {
|
|
108
|
+
readonly generation: bigint;
|
|
109
|
+
readonly handlerType: string;
|
|
110
|
+
readonly timer: ZLinkManagedTimer;
|
|
111
|
+
readonly handle: ZLinkRegisteredTimer;
|
|
112
|
+
/** Restored from a relocation payload; Configure and OnInitialize reattach it. */
|
|
113
|
+
readonly restored: boolean;
|
|
114
|
+
readonly slot: ZLinkTimerBindingSlot;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
type ZLinkTimerAddPreparation =
|
|
118
|
+
| { readonly kind: 'reattached'; readonly handle: ZLinkTimer }
|
|
119
|
+
| {
|
|
120
|
+
readonly kind: 'registered';
|
|
121
|
+
readonly previous: ZLinkTimerEntry | undefined;
|
|
122
|
+
readonly generation: bigint;
|
|
123
|
+
};
|
|
124
|
+
|
|
85
125
|
export class ZLinkSpotTimerRegistry {
|
|
86
126
|
private readonly lane = new ZLinkStateLane();
|
|
87
|
-
private readonly timers = new Map<
|
|
88
|
-
string,
|
|
89
|
-
{
|
|
90
|
-
readonly generation: bigint;
|
|
91
|
-
readonly handlerType: string;
|
|
92
|
-
readonly timer: ZLinkManagedTimer;
|
|
93
|
-
}
|
|
94
|
-
>();
|
|
127
|
+
private readonly timers = new Map<string, ZLinkTimerEntry>();
|
|
95
128
|
private readonly generations = new Map<string, bigint>();
|
|
96
129
|
private executionBarrier: ZLinkExecutionBarrier | undefined;
|
|
130
|
+
/** Frozen from the source capture or the target restore until abort or Ready. */
|
|
131
|
+
private frozen = false;
|
|
132
|
+
/**
|
|
133
|
+
* The lifecycle owner opens this window around the target's Configure and
|
|
134
|
+
* pre-Ready OnInitialize only (Spot timer §1). A registration captures it at
|
|
135
|
+
* the call, so a registration started inside the window reattaches a
|
|
136
|
+
* restored key even when its asynchronous part finishes after the window.
|
|
137
|
+
*/
|
|
138
|
+
private initializing = false;
|
|
139
|
+
/**
|
|
140
|
+
* Handler constructors the target Spot announced with `addTimer(...)` during
|
|
141
|
+
* Configure. Together with `handlers.addTimerHandler(...)` they form the
|
|
142
|
+
* table that resolves a restored timer's handler by name.
|
|
143
|
+
*/
|
|
144
|
+
private readonly configureTimerHandlers = new Set<Type>();
|
|
145
|
+
private relocationHandlersResolved = false;
|
|
97
146
|
|
|
98
147
|
constructor(
|
|
99
148
|
_metrics?: import('../diagnostics').ZLinkRuntimeMetrics,
|
|
@@ -134,60 +183,148 @@ export class ZLinkSpotTimerRegistry {
|
|
|
134
183
|
reportFailure?: ZLinkTimerFailureReporter
|
|
135
184
|
): Promise<ZLinkTimer> {
|
|
136
185
|
validateTimerRegistration(name, periodMs, options);
|
|
186
|
+
const initializing = this.initializing;
|
|
187
|
+
if (initializing && !this.relocationHandlersResolved) {
|
|
188
|
+
this.configureTimerHandlers.add(handlerType);
|
|
189
|
+
}
|
|
137
190
|
throwIfAborted(signal);
|
|
191
|
+
prepareHandlerInstance(providerResolver, handlerType);
|
|
138
192
|
const handler = await resolveLifecycleHandler(spot, handlerType, providerResolver);
|
|
139
|
-
const prepared = await this.lane.run(() => this.prepareAddCore(name));
|
|
140
|
-
if (prepared.previous !== undefined) await prepared.previous.timer.cancel(signal);
|
|
141
193
|
const executionSerial =
|
|
142
194
|
this.executeTimer === undefined
|
|
143
195
|
? (this.executionSerialForTimer?.(name, serial) ?? serial)
|
|
144
196
|
: undefined;
|
|
145
197
|
if (this.executionBarrier !== undefined)
|
|
146
198
|
executionSerial?.setExecutionBarrier(this.executionBarrier);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
callbackStarted = false;
|
|
156
|
-
const timerFlow = createInboundFlow(
|
|
157
|
-
undefined,
|
|
158
|
-
'Timer',
|
|
159
|
-
this.flowCreationEnabled(),
|
|
160
|
-
undefined
|
|
161
|
-
);
|
|
162
|
-
const operation = () => {
|
|
163
|
-
const current = this.timers.get(name);
|
|
164
|
-
if (
|
|
165
|
-
current === undefined ||
|
|
166
|
-
current.generation !== prepared.generation ||
|
|
167
|
-
current.timer !== timer
|
|
168
|
-
) {
|
|
169
|
-
return undefined;
|
|
170
|
-
}
|
|
171
|
-
if (!this.executionAllowed()) return undefined;
|
|
172
|
-
callbackStarted = true;
|
|
173
|
-
return runWithFlow(timerFlow, () => handler.handle(spot, tick));
|
|
174
|
-
};
|
|
175
|
-
if (this.executeTimer !== undefined) {
|
|
176
|
-
await this.executeTimer(name, operation);
|
|
177
|
-
} else {
|
|
178
|
-
await executionSerial!.execute(operation);
|
|
179
|
-
}
|
|
180
|
-
},
|
|
181
|
-
reportFailure,
|
|
182
|
-
() => callbackStarted,
|
|
183
|
-
this.clock
|
|
184
|
-
)
|
|
199
|
+
const binding: ZLinkTimerBinding = {
|
|
200
|
+
handler: handler as ZLinkSpotTimerHandler<ZLinkTimerOwnerSpot>,
|
|
201
|
+
spot,
|
|
202
|
+
executionSerial,
|
|
203
|
+
reportFailure
|
|
204
|
+
};
|
|
205
|
+
const prepared = await this.lane.run(() =>
|
|
206
|
+
this.prepareAddCore(name, handlerType.name, initializing, binding)
|
|
185
207
|
);
|
|
208
|
+
if (prepared.kind === 'reattached') return prepared.handle;
|
|
209
|
+
if (prepared.previous !== undefined) await prepared.previous.timer.cancel(signal);
|
|
210
|
+
const slot: ZLinkTimerBindingSlot = { binding };
|
|
211
|
+
const timer = this.createTimer(name, prepared.generation, periodMs, options, slot);
|
|
212
|
+
const handle = new ZLinkRegisteredTimer(this, name, prepared.generation, timer);
|
|
186
213
|
const registered = await this.lane.run(() =>
|
|
187
|
-
this.completeAddCore(name,
|
|
214
|
+
this.completeAddCore(name, {
|
|
215
|
+
generation: prepared.generation,
|
|
216
|
+
handlerType: handlerType.name,
|
|
217
|
+
timer,
|
|
218
|
+
handle,
|
|
219
|
+
restored: false,
|
|
220
|
+
slot
|
|
221
|
+
})
|
|
188
222
|
);
|
|
189
223
|
if (!registered) await timer.cancel(signal);
|
|
190
|
-
return
|
|
224
|
+
return handle;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Stages the source payload on a fresh relocation target before Configure.
|
|
229
|
+
* The restored registrations keep their schedule and stay frozen until Ready.
|
|
230
|
+
*/
|
|
231
|
+
stageRelocation(states: readonly ZLinkTimerRelocationState[]): void {
|
|
232
|
+
if (this.frozen || this.timers.size !== 0) {
|
|
233
|
+
throw new Error('Timer relocation can only be restored into a fresh registry.');
|
|
234
|
+
}
|
|
235
|
+
const restored = states.map((state): [string, ZLinkTimerEntry] => {
|
|
236
|
+
if (states.some((other) => other !== state && other.name === state.name)) {
|
|
237
|
+
throw new Error(`Timer '${state.name}' appears twice in relocation state.`);
|
|
238
|
+
}
|
|
239
|
+
const options = {
|
|
240
|
+
overrunPolicy: state.overrunPolicy,
|
|
241
|
+
maxCatchUpTicks: state.maxCatchUpTicks,
|
|
242
|
+
stopOnUnhandledException: state.stopOnUnhandledException
|
|
243
|
+
};
|
|
244
|
+
validateTimerRegistration(state.name, state.periodMs, options);
|
|
245
|
+
const slot: ZLinkTimerBindingSlot = { binding: undefined };
|
|
246
|
+
const timer = this.createTimer(state.name, 1n, state.periodMs, options, slot, state);
|
|
247
|
+
return [
|
|
248
|
+
state.name,
|
|
249
|
+
{
|
|
250
|
+
generation: 1n,
|
|
251
|
+
handlerType: state.handlerType,
|
|
252
|
+
timer,
|
|
253
|
+
handle: new ZLinkRegisteredTimer(this, state.name, 1n, timer),
|
|
254
|
+
restored: true,
|
|
255
|
+
slot
|
|
256
|
+
}
|
|
257
|
+
];
|
|
258
|
+
});
|
|
259
|
+
this.frozen = true;
|
|
260
|
+
for (const [name, entry] of restored) {
|
|
261
|
+
this.generations.set(name, entry.generation);
|
|
262
|
+
this.timers.set(name, entry);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Runs one relocation-target initialization callback inside the reattach window. */
|
|
267
|
+
async runRelocationInitialization<T>(operation: () => Promise<T> | T): Promise<T> {
|
|
268
|
+
if (!this.frozen || this.initializing) {
|
|
269
|
+
throw new Error('Timer relocation initialization is not active.');
|
|
270
|
+
}
|
|
271
|
+
this.initializing = true;
|
|
272
|
+
try {
|
|
273
|
+
return await operation();
|
|
274
|
+
} finally {
|
|
275
|
+
this.initializing = false;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* After Configure, resolves every restored timer's handler constructor by
|
|
281
|
+
* name among the constructors the Spot announced in Configure: `addTimer(...)`
|
|
282
|
+
* there or `handlers.addTimerHandler(...)`. A restored key that Configure did
|
|
283
|
+
* not reattach is registered with the resolved constructor so it survives
|
|
284
|
+
* Ready without re-registration. No match or more than one match fails the
|
|
285
|
+
* target restore.
|
|
286
|
+
*/
|
|
287
|
+
async resolveRelocationHandlers(
|
|
288
|
+
declared: readonly Type[],
|
|
289
|
+
register: (name: string, periodMs: number, handlerType: Type) => Promise<unknown>
|
|
290
|
+
): Promise<void> {
|
|
291
|
+
if (!this.frozen || !this.initializing || this.relocationHandlersResolved) {
|
|
292
|
+
throw new Error('Timer relocation handler resolution is not active.');
|
|
293
|
+
}
|
|
294
|
+
this.relocationHandlersResolved = true;
|
|
295
|
+
const constructors = [...new Set([...declared, ...this.configureTimerHandlers])];
|
|
296
|
+
const restored = await this.lane.run(() =>
|
|
297
|
+
[...this.timers.entries()].filter(([, entry]) => entry.restored)
|
|
298
|
+
);
|
|
299
|
+
for (const [name, entry] of restored) {
|
|
300
|
+
const matches = constructors.filter((type) => type.name === entry.handlerType);
|
|
301
|
+
if (matches.length !== 1) {
|
|
302
|
+
throw createInternalFrameworkException(
|
|
303
|
+
ZLinkFrameworkInternalErrorKind.RelocationFailed,
|
|
304
|
+
matches.length === 0
|
|
305
|
+
? `Timer '${name}' handler '${entry.handlerType}' is not declared. Register its timer with context.addTimer(...) in configure(), or declare it with context.handlers.addTimerHandler(Handler) in configure().`
|
|
306
|
+
: `Timer '${name}' handler '${entry.handlerType}' is ambiguous: ${matches.length} declared constructors share the name.`
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
if (entry.slot.binding === undefined) {
|
|
310
|
+
await register(name, entry.timer.periodMs, matches[0]!);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** Ready: starts the restored and newly registered timers. */
|
|
316
|
+
async publishRelocation(): Promise<void> {
|
|
317
|
+
await this.lane.run(() => {
|
|
318
|
+
for (const [name, entry] of this.timers) {
|
|
319
|
+
if (entry.slot.binding === undefined) {
|
|
320
|
+
throw new Error(`Restored timer '${name}' has no resolved handler at Ready.`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
this.frozen = false;
|
|
324
|
+
for (const entry of this.timers.values()) {
|
|
325
|
+
startOutsideStateLane(() => entry.timer.resume());
|
|
326
|
+
}
|
|
327
|
+
});
|
|
191
328
|
}
|
|
192
329
|
|
|
193
330
|
async dispose(): Promise<void> {
|
|
@@ -205,9 +342,10 @@ export class ZLinkSpotTimerRegistry {
|
|
|
205
342
|
}
|
|
206
343
|
|
|
207
344
|
async captureRelocation(): Promise<readonly ZLinkTimerRelocationState[]> {
|
|
208
|
-
const timers = await this.lane.run(() =>
|
|
209
|
-
|
|
210
|
-
|
|
345
|
+
const timers = await this.lane.run(() => {
|
|
346
|
+
this.frozen = true;
|
|
347
|
+
return [...this.timers.entries()].sort(([left], [right]) => left.localeCompare(right));
|
|
348
|
+
});
|
|
211
349
|
const states: ZLinkTimerRelocationState[] = [];
|
|
212
350
|
for (const [name, entry] of timers) {
|
|
213
351
|
const state = await entry.timer.captureRelocation(entry.handlerType);
|
|
@@ -217,24 +355,14 @@ export class ZLinkSpotTimerRegistry {
|
|
|
217
355
|
return states;
|
|
218
356
|
}
|
|
219
357
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
for (const [name, entry] of this.timers) {
|
|
226
|
-
const state = byName.get(name);
|
|
227
|
-
if (state === undefined) {
|
|
228
|
-
throw new Error(`Timer '${name}' is missing from relocation state.`);
|
|
229
|
-
}
|
|
230
|
-
entry.timer.restoreRelocation(state, entry.handlerType);
|
|
358
|
+
/** Source abort: the captured timers continue from their own unchanged cursor. */
|
|
359
|
+
abortRelocation(): void {
|
|
360
|
+
this.frozen = false;
|
|
361
|
+
for (const entry of this.timers.values()) {
|
|
362
|
+
startOutsideStateLane(() => entry.timer.resume());
|
|
231
363
|
}
|
|
232
364
|
}
|
|
233
365
|
|
|
234
|
-
abortRelocation(states: readonly ZLinkTimerRelocationState[]): void {
|
|
235
|
-
this.restoreRelocation(states);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
366
|
async commitRelocation(): Promise<void> {
|
|
239
367
|
await this.dispose();
|
|
240
368
|
}
|
|
@@ -250,31 +378,92 @@ export class ZLinkSpotTimerRegistry {
|
|
|
250
378
|
await timer.cancel(signal);
|
|
251
379
|
}
|
|
252
380
|
|
|
253
|
-
private
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
381
|
+
private createTimer(
|
|
382
|
+
name: string,
|
|
383
|
+
generation: bigint,
|
|
384
|
+
periodMs: number,
|
|
385
|
+
options: ZLinkTimerOptions | undefined,
|
|
386
|
+
slot: ZLinkTimerBindingSlot,
|
|
387
|
+
cursor?: ZLinkTimerRelocationState
|
|
388
|
+
): ZLinkManagedTimer {
|
|
389
|
+
let callbackStarted = false;
|
|
390
|
+
const timer: ZLinkManagedTimer = startOutsideStateLane(
|
|
391
|
+
() =>
|
|
392
|
+
new ZLinkManagedTimer(
|
|
393
|
+
name,
|
|
394
|
+
periodMs,
|
|
395
|
+
normalizeTimerOptions(options),
|
|
396
|
+
async (tick) => {
|
|
397
|
+
callbackStarted = false;
|
|
398
|
+
const binding = slot.binding;
|
|
399
|
+
if (binding === undefined) return;
|
|
400
|
+
const timerFlow = createInboundFlow(
|
|
401
|
+
undefined,
|
|
402
|
+
'Timer',
|
|
403
|
+
this.flowCreationEnabled(),
|
|
404
|
+
undefined
|
|
405
|
+
);
|
|
406
|
+
const operation = () => {
|
|
407
|
+
const current = this.timers.get(name);
|
|
408
|
+
if (
|
|
409
|
+
current === undefined ||
|
|
410
|
+
current.generation !== generation ||
|
|
411
|
+
current.timer !== timer
|
|
412
|
+
) {
|
|
413
|
+
return undefined;
|
|
414
|
+
}
|
|
415
|
+
if (!this.executionAllowed()) return undefined;
|
|
416
|
+
callbackStarted = true;
|
|
417
|
+
return runWithFlow(timerFlow, () => binding.handler.handle(binding.spot, tick));
|
|
418
|
+
};
|
|
419
|
+
if (this.executeTimer !== undefined) {
|
|
420
|
+
await this.executeTimer(name, operation);
|
|
421
|
+
} else {
|
|
422
|
+
await binding.executionSerial!.execute(operation);
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
(tick, cause, event) => slot.binding?.reportFailure?.(tick, cause, event),
|
|
426
|
+
() => callbackStarted,
|
|
427
|
+
this.clock,
|
|
428
|
+
{ paused: true, cursor }
|
|
429
|
+
)
|
|
430
|
+
);
|
|
431
|
+
return timer;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
private prepareAddCore(
|
|
435
|
+
name: string,
|
|
436
|
+
handlerType: string,
|
|
437
|
+
initializing: boolean,
|
|
438
|
+
binding: ZLinkTimerBinding
|
|
439
|
+
): ZLinkTimerAddPreparation {
|
|
440
|
+
if (this.frozen && !initializing) {
|
|
441
|
+
throw createInternalFrameworkException(
|
|
442
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
443
|
+
`Timer '${name}' registration is sealed for relocation.`
|
|
444
|
+
);
|
|
445
|
+
}
|
|
263
446
|
const previous = this.timers.get(name);
|
|
447
|
+
if (initializing && previous?.restored === true) {
|
|
448
|
+
if (previous.handlerType !== handlerType) {
|
|
449
|
+
throw createInternalFrameworkException(
|
|
450
|
+
ZLinkFrameworkInternalErrorKind.InvalidOperation,
|
|
451
|
+
`Timer '${name}' was restored with handler '${previous.handlerType}', not '${handlerType}'.`
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
previous.slot.binding = binding;
|
|
455
|
+
return { kind: 'reattached', handle: previous.handle };
|
|
456
|
+
}
|
|
264
457
|
this.timers.delete(name);
|
|
265
458
|
const generation = (this.generations.get(name) ?? 0n) + 1n;
|
|
266
459
|
this.generations.set(name, generation);
|
|
267
|
-
return { previous, generation };
|
|
460
|
+
return { kind: 'registered', previous, generation };
|
|
268
461
|
}
|
|
269
462
|
|
|
270
|
-
private completeAddCore(
|
|
271
|
-
name
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
timer: ZLinkManagedTimer
|
|
275
|
-
): boolean {
|
|
276
|
-
if (this.generations.get(name) !== generation) return false;
|
|
277
|
-
this.timers.set(name, { generation, handlerType, timer });
|
|
463
|
+
private completeAddCore(name: string, entry: ZLinkTimerEntry): boolean {
|
|
464
|
+
if (this.generations.get(name) !== entry.generation) return false;
|
|
465
|
+
this.timers.set(name, entry);
|
|
466
|
+
if (!this.frozen) startOutsideStateLane(() => entry.timer.resume());
|
|
278
467
|
return true;
|
|
279
468
|
}
|
|
280
469
|
|
|
@@ -322,24 +511,44 @@ export class ZLinkManagedTimer implements ZLinkTimer {
|
|
|
322
511
|
private pausedForRelocation = false;
|
|
323
512
|
private startedAtMs: number;
|
|
324
513
|
private startedAtUnixMs: number;
|
|
514
|
+
/** DeliveryIndex and ScheduledIndex of the last completed tick. */
|
|
325
515
|
private deliveryIndex = 0n;
|
|
326
516
|
private lastScheduledIndex = 0n;
|
|
517
|
+
/**
|
|
518
|
+
* The selected tick whose callback has not completed (Spot timer §1). It is
|
|
519
|
+
* the only pending tick a relocation captures, and a restored timer delivers
|
|
520
|
+
* it before it selects another tick.
|
|
521
|
+
*/
|
|
522
|
+
private pendingScheduledIndex: bigint | undefined;
|
|
327
523
|
private timeout: unknown;
|
|
328
|
-
|
|
524
|
+
/** The dispatch in flight, from its timer callback until `completeFireCore`. */
|
|
525
|
+
private running: Promise<void> | undefined;
|
|
329
526
|
private dispatchFailure: { readonly cause: unknown } | undefined;
|
|
330
527
|
private finalization: ZLinkTimerFinalization | undefined;
|
|
331
528
|
|
|
332
529
|
constructor(
|
|
333
530
|
private readonly name: string,
|
|
334
|
-
|
|
531
|
+
readonly periodMs: number,
|
|
335
532
|
private readonly options: Required<ZLinkTimerOptions>,
|
|
336
533
|
private readonly onTick: (tick: ZLinkTimerTick) => Promise<void>,
|
|
337
534
|
private readonly onFailure?: ZLinkTimerFailureReporter,
|
|
338
535
|
private readonly shouldWaitForRunningOnCancel: () => boolean = () => true,
|
|
339
|
-
private readonly clock: ZLinkTimerClock = systemTimerClock
|
|
536
|
+
private readonly clock: ZLinkTimerClock = systemTimerClock,
|
|
537
|
+
start: ZLinkManagedTimerStart = {}
|
|
340
538
|
) {
|
|
341
|
-
|
|
342
|
-
|
|
539
|
+
const cursor = start.cursor;
|
|
540
|
+
if (cursor === undefined) {
|
|
541
|
+
this.startedAtMs = clock.now();
|
|
542
|
+
this.startedAtUnixMs = clock.utcNow();
|
|
543
|
+
} else {
|
|
544
|
+
validateRelocationCursor(name, periodMs, cursor);
|
|
545
|
+
this.startedAtUnixMs = cursor.startedAtUnixMs;
|
|
546
|
+
this.startedAtMs = clock.now() - Math.max(0, clock.utcNow() - cursor.startedAtUnixMs);
|
|
547
|
+
this.deliveryIndex = cursor.deliveryIndex;
|
|
548
|
+
this.lastScheduledIndex = cursor.lastScheduledIndex;
|
|
549
|
+
this.pendingScheduledIndex = cursor.pendingTicks[0]?.scheduledIndex;
|
|
550
|
+
}
|
|
551
|
+
this.pausedForRelocation = start.paused === true;
|
|
343
552
|
this.scheduleNext();
|
|
344
553
|
}
|
|
345
554
|
|
|
@@ -388,59 +597,44 @@ export class ZLinkManagedTimer implements ZLinkTimer {
|
|
|
388
597
|
deliveryIndex: this.deliveryIndex,
|
|
389
598
|
lastScheduledIndex: this.lastScheduledIndex,
|
|
390
599
|
nextDueAtUnixMs: this.startedAtUnixMs + Number(this.lastScheduledIndex + 1n) * this.periodMs,
|
|
391
|
-
pendingTicks:
|
|
600
|
+
pendingTicks:
|
|
601
|
+
this.pendingScheduledIndex === undefined
|
|
602
|
+
? []
|
|
603
|
+
: [this.pendingTick(this.pendingScheduledIndex)]
|
|
392
604
|
}));
|
|
393
605
|
}
|
|
394
606
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
if (
|
|
398
|
-
state.name !== this.name ||
|
|
399
|
-
state.handlerType !== handlerType ||
|
|
400
|
-
state.periodMs !== this.periodMs ||
|
|
401
|
-
state.overrunPolicy !== this.options.overrunPolicy ||
|
|
402
|
-
state.maxCatchUpTicks !== this.options.maxCatchUpTicks ||
|
|
403
|
-
state.stopOnUnhandledException !== this.options.stopOnUnhandledException ||
|
|
404
|
-
!Number.isSafeInteger(state.startedAtUnixMs) ||
|
|
405
|
-
state.deliveryIndex < 0n ||
|
|
406
|
-
state.lastScheduledIndex < 0n ||
|
|
407
|
-
!Number.isSafeInteger(state.nextDueAtUnixMs) ||
|
|
408
|
-
state.nextDueAtUnixMs !==
|
|
409
|
-
state.startedAtUnixMs + Number(state.lastScheduledIndex + 1n) * state.periodMs ||
|
|
410
|
-
state.pendingTicks.length !== 0
|
|
411
|
-
) {
|
|
412
|
-
throw new Error(`Timer '${this.name}' relocation contract does not match its registration.`);
|
|
413
|
-
}
|
|
414
|
-
if (this.timeout !== undefined) this.clock.clearTimeout(this.timeout);
|
|
415
|
-
this.timeout = undefined;
|
|
416
|
-
this.startedAtUnixMs = state.startedAtUnixMs;
|
|
417
|
-
this.startedAtMs = this.clock.now() - Math.max(0, this.clock.utcNow() - state.startedAtUnixMs);
|
|
418
|
-
this.deliveryIndex = state.deliveryIndex;
|
|
419
|
-
this.lastScheduledIndex = state.lastScheduledIndex;
|
|
607
|
+
/** Starts a timer created paused, or continues one paused by a relocation capture. */
|
|
608
|
+
resume(): void {
|
|
609
|
+
if (this.disposed || !this.pausedForRelocation) return;
|
|
420
610
|
this.pausedForRelocation = false;
|
|
421
611
|
this.scheduleNext();
|
|
422
612
|
}
|
|
423
613
|
|
|
424
614
|
private scheduleNext(): void {
|
|
425
|
-
|
|
615
|
+
// The dispatch in flight schedules the next tick when it completes.
|
|
616
|
+
if (this.disposed || this.pausedForRelocation || this.running !== undefined) {
|
|
426
617
|
return;
|
|
427
618
|
}
|
|
428
619
|
|
|
429
620
|
const delayMs =
|
|
430
|
-
this.
|
|
431
|
-
?
|
|
432
|
-
:
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
this.
|
|
437
|
-
|
|
438
|
-
(
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
621
|
+
this.pendingScheduledIndex !== undefined
|
|
622
|
+
? 0
|
|
623
|
+
: this.options.overrunPolicy === ZLinkTimerOverrunPolicy.DelayNextTick
|
|
624
|
+
? this.periodMs
|
|
625
|
+
: Math.max(0, Number(this.lastScheduledIndex + 1n) * this.periodMs - this.elapsedMs());
|
|
626
|
+
this.timeout = startOutsideStateLane(() =>
|
|
627
|
+
this.clock.setTimeout(() => {
|
|
628
|
+
this.timeout = undefined;
|
|
629
|
+
this.running = this.fire().then(
|
|
630
|
+
() => undefined,
|
|
631
|
+
(cause) =>
|
|
632
|
+
this.lane.run(() => {
|
|
633
|
+
this.dispatchFailure ??= { cause };
|
|
634
|
+
})
|
|
635
|
+
);
|
|
636
|
+
}, delayMs)
|
|
637
|
+
);
|
|
444
638
|
}
|
|
445
639
|
|
|
446
640
|
private async fire(): Promise<void> {
|
|
@@ -451,6 +645,11 @@ export class ZLinkManagedTimer implements ZLinkTimer {
|
|
|
451
645
|
try {
|
|
452
646
|
await this.onTick(prepared.tick);
|
|
453
647
|
} catch (cause) {
|
|
648
|
+
// A tick whose callback had not started when a relocation captured it
|
|
649
|
+
// belongs to the capture: the target delivers it, so the source neither
|
|
650
|
+
// reports nor completes it.
|
|
651
|
+
const started = this.shouldWaitForRunningOnCancel();
|
|
652
|
+
if (!started && (await this.lane.run(() => this.pausedForRelocation))) return;
|
|
454
653
|
shouldContinue = !this.options.stopOnUnhandledException;
|
|
455
654
|
await this.onFailure?.(
|
|
456
655
|
prepared.tick,
|
|
@@ -461,7 +660,7 @@ export class ZLinkManagedTimer implements ZLinkTimer {
|
|
|
461
660
|
);
|
|
462
661
|
}
|
|
463
662
|
|
|
464
|
-
await this.lane.run(() => this.completeFireCore(
|
|
663
|
+
await this.lane.run(() => this.completeFireCore(shouldContinue));
|
|
465
664
|
}
|
|
466
665
|
|
|
467
666
|
private cancelCore(): ZLinkTimerFinalizationStart {
|
|
@@ -470,7 +669,7 @@ export class ZLinkManagedTimer implements ZLinkTimer {
|
|
|
470
669
|
this.timeout = undefined;
|
|
471
670
|
return {
|
|
472
671
|
timeout,
|
|
473
|
-
running: this.shouldWaitForRunningOnCancel() ? this.running :
|
|
672
|
+
running: this.shouldWaitForRunningOnCancel() ? this.running : undefined
|
|
474
673
|
};
|
|
475
674
|
}
|
|
476
675
|
|
|
@@ -503,43 +702,54 @@ export class ZLinkManagedTimer implements ZLinkTimer {
|
|
|
503
702
|
}
|
|
504
703
|
}
|
|
505
704
|
|
|
506
|
-
private prepareCaptureCore(): { readonly running: Promise<void> } {
|
|
705
|
+
private prepareCaptureCore(): { readonly running: Promise<void> | undefined } {
|
|
507
706
|
if (this.disposed) throw new Error(`Timer '${this.name}' is disposed.`);
|
|
508
707
|
this.pausedForRelocation = true;
|
|
509
708
|
if (this.timeout !== undefined) {
|
|
510
709
|
this.clock.clearTimeout(this.timeout);
|
|
511
710
|
this.timeout = undefined;
|
|
512
711
|
}
|
|
513
|
-
return { running: this.shouldWaitForRunningOnCancel() ? this.running :
|
|
712
|
+
return { running: this.shouldWaitForRunningOnCancel() ? this.running : undefined };
|
|
514
713
|
}
|
|
515
714
|
|
|
516
|
-
private prepareFireCore():
|
|
517
|
-
{ readonly tick: ZLinkTimerTick; readonly scheduledIndex: bigint } | undefined {
|
|
715
|
+
private prepareFireCore(): { readonly tick: ZLinkTimerTick } | undefined {
|
|
518
716
|
if (this.disposed) return undefined;
|
|
519
|
-
|
|
520
|
-
const
|
|
717
|
+
this.pendingScheduledIndex ??= this.selectScheduledIndex();
|
|
718
|
+
const pending = this.pendingTick(this.pendingScheduledIndex);
|
|
521
719
|
const startedElapsedMs = this.elapsedMs();
|
|
522
|
-
const scheduledElapsedMs = Number(scheduledIndex) * this.periodMs;
|
|
523
|
-
this.deliveryIndex += 1n;
|
|
720
|
+
const scheduledElapsedMs = Number(pending.scheduledIndex) * this.periodMs;
|
|
524
721
|
return {
|
|
525
|
-
scheduledIndex,
|
|
526
722
|
tick: {
|
|
527
723
|
name: this.name,
|
|
528
|
-
deliveryIndex:
|
|
529
|
-
scheduledIndex,
|
|
724
|
+
deliveryIndex: pending.deliveryIndex,
|
|
725
|
+
scheduledIndex: pending.scheduledIndex,
|
|
530
726
|
periodMs: this.periodMs,
|
|
531
|
-
scheduledAt: new Date(
|
|
727
|
+
scheduledAt: new Date(pending.scheduledAtUnixMs),
|
|
532
728
|
startedAt: new Date(this.clock.utcNow()),
|
|
533
729
|
scheduledElapsedMs,
|
|
534
730
|
startedElapsedMs,
|
|
535
731
|
delayMs: startedElapsedMs - scheduledElapsedMs,
|
|
536
|
-
skippedTicks
|
|
732
|
+
skippedTicks: pending.skippedTicks
|
|
537
733
|
}
|
|
538
734
|
};
|
|
539
735
|
}
|
|
540
736
|
|
|
541
|
-
|
|
542
|
-
|
|
737
|
+
/** The tick info of the pending tick at `scheduledIndex` after the completed cursor. */
|
|
738
|
+
private pendingTick(scheduledIndex: bigint): ZLinkTimerRelocationPendingTick {
|
|
739
|
+
return relocationPendingTick(
|
|
740
|
+
this.startedAtUnixMs,
|
|
741
|
+
this.periodMs,
|
|
742
|
+
this.deliveryIndex,
|
|
743
|
+
this.lastScheduledIndex,
|
|
744
|
+
scheduledIndex
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
private completeFireCore(shouldContinue: boolean): void {
|
|
749
|
+
this.deliveryIndex += 1n;
|
|
750
|
+
this.lastScheduledIndex = this.pendingScheduledIndex!;
|
|
751
|
+
this.pendingScheduledIndex = undefined;
|
|
752
|
+
this.running = undefined;
|
|
543
753
|
if (!shouldContinue) {
|
|
544
754
|
this.disposed = true;
|
|
545
755
|
return;
|
|
@@ -576,8 +786,58 @@ export class ZLinkManagedTimer implements ZLinkTimer {
|
|
|
576
786
|
}
|
|
577
787
|
}
|
|
578
788
|
|
|
579
|
-
function
|
|
580
|
-
|
|
789
|
+
function validateRelocationCursor(
|
|
790
|
+
name: string,
|
|
791
|
+
periodMs: number,
|
|
792
|
+
state: ZLinkTimerRelocationState
|
|
793
|
+
): void {
|
|
794
|
+
if (
|
|
795
|
+
state.name !== name ||
|
|
796
|
+
state.periodMs !== periodMs ||
|
|
797
|
+
!Number.isSafeInteger(state.startedAtUnixMs) ||
|
|
798
|
+
state.deliveryIndex < 0n ||
|
|
799
|
+
state.lastScheduledIndex < 0n ||
|
|
800
|
+
!Number.isSafeInteger(state.nextDueAtUnixMs) ||
|
|
801
|
+
state.nextDueAtUnixMs !==
|
|
802
|
+
state.startedAtUnixMs + Number(state.lastScheduledIndex + 1n) * state.periodMs ||
|
|
803
|
+
state.pendingTicks.length > 1 ||
|
|
804
|
+
state.pendingTicks.some((pending) => {
|
|
805
|
+
const expected = relocationPendingTick(
|
|
806
|
+
state.startedAtUnixMs,
|
|
807
|
+
state.periodMs,
|
|
808
|
+
state.deliveryIndex,
|
|
809
|
+
state.lastScheduledIndex,
|
|
810
|
+
pending.scheduledIndex
|
|
811
|
+
);
|
|
812
|
+
return (
|
|
813
|
+
pending.scheduledIndex <= state.lastScheduledIndex ||
|
|
814
|
+
pending.deliveryIndex !== expected.deliveryIndex ||
|
|
815
|
+
pending.scheduledAtUnixMs !== expected.scheduledAtUnixMs ||
|
|
816
|
+
pending.skippedTicks !== expected.skippedTicks
|
|
817
|
+
);
|
|
818
|
+
})
|
|
819
|
+
) {
|
|
820
|
+
throw new Error(`Timer '${name}' relocation state is invalid.`);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* Spot timer §1: the tick info that follows the completed cursor. A timer holds
|
|
826
|
+
* at most one pending tick, so its DeliveryIndex is the next one.
|
|
827
|
+
*/
|
|
828
|
+
function relocationPendingTick(
|
|
829
|
+
startedAtUnixMs: number,
|
|
830
|
+
periodMs: number,
|
|
831
|
+
deliveryIndex: bigint,
|
|
832
|
+
lastScheduledIndex: bigint,
|
|
833
|
+
scheduledIndex: bigint
|
|
834
|
+
): ZLinkTimerRelocationPendingTick {
|
|
835
|
+
return {
|
|
836
|
+
deliveryIndex: deliveryIndex + 1n,
|
|
837
|
+
scheduledIndex,
|
|
838
|
+
scheduledAtUnixMs: startedAtUnixMs + Number(scheduledIndex) * periodMs,
|
|
839
|
+
skippedTicks: scheduledIndex - lastScheduledIndex - 1n
|
|
840
|
+
};
|
|
581
841
|
}
|
|
582
842
|
|
|
583
843
|
export function createTimerDiagnostics(
|