@zlink-systems/framework 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Common/CoreTypes.d.ts +6 -0
- package/dist/contracts/Common/CoreTypes.js +7 -0
- package/dist/contracts/Common/index.d.ts +1 -1
- package/dist/contracts/Common/index.js +0 -1
- package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
- package/dist/contracts/Configuration/InternalDefaults.js +9 -1
- package/dist/contracts/Configuration/Registration.d.ts +13 -2
- package/dist/contracts/Configuration/Registration.js +58 -36
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
- package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
- package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
- package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
- package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
- package/dist/contracts/Configuration/RegistrationValidators.js +15 -12
- package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
- package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
- package/dist/contracts/Handlers/JsonContract.js +10 -4
- package/dist/contracts/Locations/Authority.d.ts +1 -1
- package/dist/contracts/Locations/Authority.js +3 -2
- package/dist/contracts/Locations/Options.js +1 -1
- package/dist/contracts/Locations/Stores.d.ts +12 -0
- package/dist/contracts/Locations/Stores.js +9 -0
- package/dist/contracts/Spots/Contracts.d.ts +1 -1
- package/dist/internal.d.ts +4 -0
- package/dist/internal.js +15 -1
- package/dist/nest-integration.d.ts +4 -2
- package/dist/nest-integration.js +14 -4
- package/dist/runtime/abort.d.ts +1 -0
- package/dist/runtime/abort.js +8 -5
- package/dist/runtime/activation-admission.d.ts +1 -2
- package/dist/runtime/activation-admission.js +2 -6
- package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
- package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
- package/dist/runtime/actors/actor-client.d.ts +2 -2
- package/dist/runtime/actors/actor-client.js +42 -143
- package/dist/runtime/actors/actor-context.d.ts +3 -5
- package/dist/runtime/actors/actor-context.js +13 -11
- package/dist/runtime/actors/actor-handoff.d.ts +4 -4
- package/dist/runtime/actors/actor-handoff.js +8 -8
- package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
- package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
- package/dist/runtime/actors/actor-local-native-join.js +83 -105
- package/dist/runtime/actors/actor-native-lookup.js +2 -8
- package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
- package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
- package/dist/runtime/actors/actor-remote-joiner.d.ts +1 -1
- package/dist/runtime/actors/actor-remote-joiner.js +5 -9
- package/dist/runtime/actors/actor-remote-wire.js +5 -3
- package/dist/runtime/actors/actor-request-deadline.d.ts +3 -0
- package/dist/runtime/actors/actor-request-deadline.js +31 -0
- package/dist/runtime/actors/actor-retry-delay.js +2 -1
- package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
- package/dist/runtime/actors/actor-runtime-state.js +70 -187
- package/dist/runtime/actors/bound-session-wire.js +2 -7
- package/dist/runtime/actors/deferred-join-completion.d.ts +11 -6
- package/dist/runtime/actors/deferred-join-completion.js +1 -0
- package/dist/runtime/actors/index.d.ts +9 -7
- package/dist/runtime/actors/index.js +87 -69
- package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
- package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
- package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
- package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
- package/dist/runtime/admission.d.ts +2 -0
- package/dist/runtime/admission.js +7 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
- package/dist/runtime/backend/contracts/index.d.ts +6 -23
- package/dist/runtime/backend/mesh-actor-session-node-adapter.js +1 -17
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
- package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +1 -1
- package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -6
- package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
- package/dist/runtime/backend/node/node-event-loop-poller.js +6 -7
- package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
- package/dist/runtime/backend/node/node-raw-binding-port.js +40 -16
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +14 -15
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +146 -118
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +3 -2
- package/dist/runtime/backend/raw-binding-port.d.ts +1 -1
- package/dist/runtime/backend/runtime-values.d.ts +4 -1
- package/dist/runtime/backend/runtime-values.js +2 -0
- package/dist/runtime/channels/channel-clients.d.ts +20 -8
- package/dist/runtime/channels/channel-clients.js +68 -52
- package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
- package/dist/runtime/channels/channel-envelope.js +47 -29
- package/dist/runtime/channels/channel-outbound-operations.d.ts +3 -0
- package/dist/runtime/channels/channel-outbound-operations.js +9 -10
- package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
- package/dist/runtime/channels/channel-receive-loops.js +27 -6
- package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
- package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
- package/dist/runtime/channels/channel-runtime-manager.js +5 -2
- package/dist/runtime/channels/channel-socket-options.js +3 -2
- package/dist/runtime/channels/channel-socket-registry.d.ts +14 -29
- package/dist/runtime/channels/channel-socket-registry.js +248 -174
- package/dist/runtime/channels/channel-transports.d.ts +11 -17
- package/dist/runtime/channels/channel-transports.js +68 -47
- package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
- package/dist/runtime/channels/client-server-location-runtime.js +10 -11
- package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
- package/dist/runtime/channels/client-server-service-wire.js +32 -11
- package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
- package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
- package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
- package/dist/runtime/channels/fanout-location-runtime.js +130 -72
- package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
- package/dist/runtime/channels/spot-direct-envelope.js +4 -3
- package/dist/runtime/channels/spot-node-route-transport.js +3 -2
- package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
- package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
- package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
- package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
- package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
- package/dist/runtime/diagnostics/flow-context.js +16 -2
- package/dist/runtime/diagnostics/index.d.ts +4 -2
- package/dist/runtime/diagnostics/index.js +14 -4
- package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
- package/dist/runtime/diagnostics/message-flow.js +10 -19
- package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
- package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
- package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
- package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
- package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
- package/dist/runtime/disposal.d.ts +5 -0
- package/dist/runtime/disposal.js +22 -0
- package/dist/runtime/execution/index.d.ts +12 -9
- package/dist/runtime/execution/index.js +58 -14
- package/dist/runtime/execution/serial-execution-queue.d.ts +8 -2
- package/dist/runtime/execution/serial-execution-queue.js +54 -15
- package/dist/runtime/execution/state-lane.d.ts +8 -1
- package/dist/runtime/execution/state-lane.js +118 -3
- package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
- package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
- package/dist/runtime/foundation/event-loop-resources.js +6 -119
- package/dist/runtime/foundation/operation-identity.d.ts +2 -0
- package/dist/runtime/foundation/operation-identity.js +9 -5
- package/dist/runtime/foundation/operation-registry.d.ts +5 -7
- package/dist/runtime/foundation/operation-registry.js +34 -44
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +8 -5
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +62 -83
- package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
- package/dist/runtime/foundation/runtime-state-projections.js +8 -0
- package/dist/runtime/foundation/service-authority-payload-codec.js +22 -12
- package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
- package/dist/runtime/foundation/service-discovery-registry.js +22 -3
- package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
- package/dist/runtime/foundation/service-liveness-registry.js +2 -1
- package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
- package/dist/runtime/foundation/service-maintenance-runtime.js +0 -6
- package/dist/runtime/foundation/service-metadata-codec.js +3 -3
- package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
- package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
- package/dist/runtime/foundation/service-relocation-object-owner.js +3 -2
- package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
- package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
- package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -12
- package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-registry.js +10 -2
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +26 -25
- package/dist/runtime/foundation/service-stateful-runtime.js +217 -204
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -3
- package/dist/runtime/foundation/service-stateful-wire-codec.js +89 -55
- package/dist/runtime/foundation/service-topology-registry.d.ts +0 -1
- package/dist/runtime/foundation/service-topology-registry.js +17 -32
- package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
- package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
- package/dist/runtime/foundation/service-wire-codec.js +10 -8
- package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
- package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
- package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
- package/dist/runtime/framework-errors-internal.d.ts +2 -1
- package/dist/runtime/framework-errors-internal.js +343 -122
- package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
- package/dist/runtime/handlers/handler-instance-scope.js +61 -74
- package/dist/runtime/host/actor-packet-relay.d.ts +9 -6
- package/dist/runtime/host/actor-packet-relay.js +48 -91
- package/dist/runtime/host/actor-placement-coordinator.js +7 -5
- package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
- package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
- package/dist/runtime/host/actor-transfer-runtime.d.ts +16 -18
- package/dist/runtime/host/actor-transfer-runtime.js +143 -176
- package/dist/runtime/host/application-job-queue.js +16 -33
- package/dist/runtime/host/bound-session-relay.js +1 -1
- package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
- package/dist/runtime/host/index.d.ts +14 -13
- package/dist/runtime/host/index.js +190 -157
- package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
- package/dist/runtime/host/instance-activation-authority.js +17 -45
- package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
- package/dist/runtime/host/location-runtime-owner.js +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
- package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
- package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
- package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
- package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
- package/dist/runtime/host/remote-bound-session-relay.js +7 -20
- package/dist/runtime/host/route-mesh-runtime.d.ts +13 -11
- package/dist/runtime/host/route-mesh-runtime.js +171 -252
- package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
- package/dist/runtime/host/runtime-shutdown.js +18 -21
- package/dist/runtime/host/service-relocation-control.js +6 -1
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +21 -30
- package/dist/runtime/host/service-relocation-host-runtime.js +508 -416
- package/dist/runtime/host/spot-address-transport.d.ts +2 -3
- package/dist/runtime/host/spot-address-transport.js +34 -136
- package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
- package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -10
- package/dist/runtime/host/spot-runtime-options-factory.js +50 -14
- package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -3
- package/dist/runtime/host/user-spot-creation-coordinator.js +11 -8
- package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
- package/dist/runtime/locations/authority-key-codec.js +4 -3
- package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
- package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
- package/dist/runtime/locations/creation-operation-id.js +6 -4
- package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
- package/dist/runtime/locations/in-memory-authority-store.js +31 -15
- package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
- package/dist/runtime/locations/in-memory-location-store.js +17 -14
- package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
- package/dist/runtime/locations/in-memory-provider-location-store.js +72 -22
- package/dist/runtime/locations/key-codec.js +3 -2
- package/dist/runtime/locations/lease-tracker.d.ts +3 -5
- package/dist/runtime/locations/lease-tracker.js +7 -11
- package/dist/runtime/locations/lifecycle.d.ts +4 -9
- package/dist/runtime/locations/lifecycle.js +2 -31
- package/dist/runtime/locations/location-store-failure.d.ts +2 -0
- package/dist/runtime/locations/location-store-failure.js +7 -0
- package/dist/runtime/locations/location-store-pages.d.ts +3 -0
- package/dist/runtime/locations/location-store-pages.js +13 -0
- package/dist/runtime/locations/location-store-repository.d.ts +5 -7
- package/dist/runtime/locations/location-store-repository.js +303 -332
- package/dist/runtime/locations/relocation-blob.js +18 -5
- package/dist/runtime/locations/resolvers.d.ts +5 -5
- package/dist/runtime/locations/resolvers.js +37 -28
- package/dist/runtime/locations/runtime.d.ts +5 -4
- package/dist/runtime/locations/runtime.js +123 -92
- package/dist/runtime/locations/spot-location-claims.d.ts +6 -0
- package/dist/runtime/locations/spot-location-claims.js +42 -1
- package/dist/runtime/messaging/payload-codec.js +26 -20
- package/dist/runtime/messaging/submission-result.d.ts +3 -0
- package/dist/runtime/messaging/submission-result.js +48 -0
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +12 -7
- package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +4 -1
- package/dist/runtime/spots/index.d.ts +14 -20
- package/dist/runtime/spots/index.js +302 -176
- package/dist/runtime/spots/spot-activation-registry.d.ts +3 -5
- package/dist/runtime/spots/spot-activation-registry.js +14 -50
- package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
- package/dist/runtime/spots/spot-activation-state.js +2 -2
- package/dist/runtime/spots/spot-activation.d.ts +3 -4
- package/dist/runtime/spots/spot-activation.js +49 -32
- package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
- package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
- package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
- package/dist/runtime/spots/spot-actor-join-dispatch.js +4 -52
- package/dist/runtime/spots/spot-actor-membership.d.ts +4 -6
- package/dist/runtime/spots/spot-actor-membership.js +22 -45
- package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
- package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
- package/dist/runtime/spots/spot-context.d.ts +2 -2
- package/dist/runtime/spots/spot-entry-activation.d.ts +2 -2
- package/dist/runtime/spots/spot-entry-activation.js +9 -20
- package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
- package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
- package/dist/runtime/spots/spot-manager-public.js +5 -4
- package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
- package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -18
- package/dist/runtime/spots/spot-node-runtime-manager.js +67 -72
- package/dist/runtime/spots/spot-outbound.d.ts +4 -3
- package/dist/runtime/spots/spot-outbound.js +9 -8
- package/dist/runtime/spots/spot-remote-codec.js +5 -3
- package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
- package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
- package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
- package/dist/runtime/spots/spot-route-replies.js +3 -1
- package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -3
- package/dist/runtime/spots/spot-routed-actor-admission.js +3 -12
- package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +1 -2
- package/dist/runtime/spots/spot-routed-frame-dispatch.js +0 -1
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
- package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -16
- package/dist/runtime/spots/spot-serial-executor.js +2 -2
- package/dist/runtime/spots/spot-serial-turn-executor.d.ts +27 -7
- package/dist/runtime/spots/spot-serial-turn-executor.js +83 -11
- package/dist/runtime/spots/spot-timer.d.ts +3 -2
- package/dist/runtime/streams/actor-session-binding-registry.d.ts +16 -29
- package/dist/runtime/streams/actor-session-binding-registry.js +142 -212
- package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -4
- package/dist/runtime/streams/bound-actor-relay-sender.d.ts +6 -2
- package/dist/runtime/streams/bound-actor-relay-sender.js +57 -33
- package/dist/runtime/streams/bound-session-service.d.ts +7 -0
- package/dist/runtime/streams/bound-session-service.js +11 -1
- package/dist/runtime/streams/index.d.ts +14 -15
- package/dist/runtime/streams/index.js +20 -21
- package/dist/runtime/streams/managed-stream.d.ts +3 -0
- package/dist/runtime/streams/managed-stream.js +17 -8
- package/dist/runtime/streams/native-fallback-bound-session.js +1 -3
- package/dist/runtime/streams/protocol.d.ts +6 -33
- package/dist/runtime/streams/protocol.js +38 -110
- package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
- package/dist/runtime/streams/session-actor-coordinator.js +12 -4
- package/dist/runtime/streams/session-calls.d.ts +1 -1
- package/dist/runtime/streams/session-calls.js +5 -4
- package/dist/runtime/streams/session-context.d.ts +6 -6
- package/dist/runtime/streams/session-context.js +22 -4
- package/dist/runtime/streams/session-requests.js +2 -1
- package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
- package/dist/runtime/streams/stream-frame-factory.js +2 -2
- package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
- package/dist/runtime/streams/stream-session-runtime.js +25 -33
- package/dist/runtime/workers/index.d.ts +2 -2
- package/dist/runtime/workers/index.js +5 -4
- package/package.json +3 -3
- package/src/contracts/Common/CoreTypes.ts +7 -0
- package/src/contracts/Common/index.ts +1 -1
- package/src/contracts/Configuration/InternalDefaults.ts +12 -0
- package/src/contracts/Configuration/Registration.ts +92 -48
- package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
- package/src/contracts/Configuration/RegistrationBuilders.ts +77 -68
- package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
- package/src/contracts/Configuration/RegistrationValidators.ts +19 -13
- package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
- package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
- package/src/contracts/Handlers/JsonContract.ts +14 -4
- package/src/contracts/Locations/Authority.ts +7 -3
- package/src/contracts/Locations/Options.ts +1 -1
- package/src/contracts/Locations/Stores.ts +14 -0
- package/src/contracts/Spots/Contracts.ts +1 -1
- package/src/internal.ts +14 -0
- package/src/nest-integration.ts +28 -10
- package/src/runtime/abort.ts +6 -5
- package/src/runtime/activation-admission.ts +2 -8
- package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
- package/src/runtime/actors/actor-client.ts +77 -204
- package/src/runtime/actors/actor-context.ts +39 -33
- package/src/runtime/actors/actor-handoff.ts +24 -22
- package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
- package/src/runtime/actors/actor-local-native-join.ts +172 -174
- package/src/runtime/actors/actor-native-lookup.ts +2 -9
- package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
- package/src/runtime/actors/actor-remote-joiner.ts +9 -11
- package/src/runtime/actors/actor-remote-wire.ts +5 -3
- package/src/runtime/actors/actor-request-deadline.ts +49 -0
- package/src/runtime/actors/actor-retry-delay.ts +2 -1
- package/src/runtime/actors/actor-runtime-state.ts +85 -247
- package/src/runtime/actors/bound-session-wire.ts +2 -8
- package/src/runtime/actors/deferred-join-completion.ts +10 -6
- package/src/runtime/actors/index.ts +100 -79
- package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
- package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
- package/src/runtime/admission.ts +8 -1
- package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
- package/src/runtime/backend/contracts/index.ts +13 -29
- package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -18
- package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
- package/src/runtime/backend/node/node-backend-adapter-support.ts +23 -6
- package/src/runtime/backend/node/node-event-loop-poller.ts +8 -12
- package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
- package/src/runtime/backend/node/node-raw-binding-port.ts +41 -20
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +227 -170
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +3 -2
- package/src/runtime/backend/raw-binding-port.ts +1 -1
- package/src/runtime/backend/runtime-values.ts +4 -1
- package/src/runtime/channels/channel-clients.ts +132 -85
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
- package/src/runtime/channels/channel-envelope.ts +58 -29
- package/src/runtime/channels/channel-outbound-operations.ts +10 -23
- package/src/runtime/channels/channel-receive-loops.ts +39 -7
- package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
- package/src/runtime/channels/channel-runtime-manager.ts +6 -2
- package/src/runtime/channels/channel-socket-options.ts +8 -2
- package/src/runtime/channels/channel-socket-registry.ts +301 -192
- package/src/runtime/channels/channel-transports.ts +161 -112
- package/src/runtime/channels/client-server-location-runtime.ts +17 -17
- package/src/runtime/channels/client-server-service-wire.ts +40 -12
- package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
- package/src/runtime/channels/fanout-location-runtime.ts +172 -91
- package/src/runtime/channels/spot-direct-envelope.ts +1 -1
- package/src/runtime/channels/spot-node-route-transport.ts +5 -2
- package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
- package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
- package/src/runtime/diagnostics/flow-context.ts +16 -2
- package/src/runtime/diagnostics/index.ts +27 -17
- package/src/runtime/diagnostics/message-flow.ts +15 -25
- package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
- package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
- package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
- package/src/runtime/disposal.ts +19 -0
- package/src/runtime/execution/index.ts +60 -20
- package/src/runtime/execution/serial-execution-queue.ts +131 -18
- package/src/runtime/execution/state-lane.ts +142 -4
- package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
- package/src/runtime/foundation/event-loop-resources.ts +5 -122
- package/src/runtime/foundation/operation-identity.ts +11 -5
- package/src/runtime/foundation/operation-registry.ts +33 -50
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +110 -111
- package/src/runtime/foundation/runtime-state-projections.ts +9 -1
- package/src/runtime/foundation/service-authority-payload-codec.ts +31 -13
- package/src/runtime/foundation/service-discovery-registry.ts +32 -3
- package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
- package/src/runtime/foundation/service-liveness-registry.ts +2 -1
- package/src/runtime/foundation/service-maintenance-runtime.ts +0 -10
- package/src/runtime/foundation/service-metadata-codec.ts +2 -2
- package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
- package/src/runtime/foundation/service-relocation-object-owner.ts +5 -2
- package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
- package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
- package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -17
- package/src/runtime/foundation/service-stateful-registry.ts +14 -2
- package/src/runtime/foundation/service-stateful-runtime.ts +322 -276
- package/src/runtime/foundation/service-stateful-wire-codec.ts +128 -80
- package/src/runtime/foundation/service-topology-registry.ts +23 -32
- package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
- package/src/runtime/foundation/service-wire-codec.ts +15 -8
- package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
- package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
- package/src/runtime/framework-errors-internal.ts +380 -134
- package/src/runtime/handlers/handler-instance-scope.ts +68 -95
- package/src/runtime/host/actor-packet-relay.ts +57 -147
- package/src/runtime/host/actor-placement-coordinator.ts +8 -5
- package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
- package/src/runtime/host/actor-transfer-runtime.ts +180 -260
- package/src/runtime/host/application-job-queue.ts +28 -34
- package/src/runtime/host/bound-session-relay.ts +1 -2
- package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
- package/src/runtime/host/index.ts +327 -296
- package/src/runtime/host/instance-activation-authority.ts +89 -109
- package/src/runtime/host/location-runtime-owner.ts +4 -2
- package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
- package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
- package/src/runtime/host/remote-bound-session-relay.ts +8 -41
- package/src/runtime/host/route-mesh-runtime.ts +228 -271
- package/src/runtime/host/runtime-shutdown.ts +17 -21
- package/src/runtime/host/service-relocation-control.ts +14 -1
- package/src/runtime/host/service-relocation-host-runtime.ts +699 -561
- package/src/runtime/host/spot-address-transport.ts +73 -195
- package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
- package/src/runtime/host/spot-runtime-options-factory.ts +73 -22
- package/src/runtime/host/user-spot-creation-coordinator.ts +36 -22
- package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
- package/src/runtime/locations/authority-key-codec.ts +7 -3
- package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
- package/src/runtime/locations/creation-operation-id.ts +6 -3
- package/src/runtime/locations/domain-store-contract.ts +12 -3
- package/src/runtime/locations/in-memory-authority-store.ts +44 -15
- package/src/runtime/locations/in-memory-location-store.ts +50 -39
- package/src/runtime/locations/in-memory-provider-location-store.ts +100 -25
- package/src/runtime/locations/key-codec.ts +3 -2
- package/src/runtime/locations/lease-tracker.ts +8 -14
- package/src/runtime/locations/lifecycle.ts +13 -43
- package/src/runtime/locations/location-store-failure.ts +4 -0
- package/src/runtime/locations/location-store-pages.ts +18 -0
- package/src/runtime/locations/location-store-repository.ts +450 -478
- package/src/runtime/locations/relocation-blob.ts +17 -6
- package/src/runtime/locations/resolvers.ts +75 -49
- package/src/runtime/locations/runtime.ts +220 -110
- package/src/runtime/locations/spot-location-claims.ts +58 -1
- package/src/runtime/messaging/payload-codec.ts +35 -24
- package/src/runtime/messaging/submission-result.ts +57 -1
- package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
- package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +4 -1
- package/src/runtime/spots/index.ts +433 -229
- package/src/runtime/spots/spot-activation-registry.ts +30 -69
- package/src/runtime/spots/spot-activation-state.ts +2 -2
- package/src/runtime/spots/spot-activation.ts +67 -37
- package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
- package/src/runtime/spots/spot-actor-join-dispatch.ts +24 -77
- package/src/runtime/spots/spot-actor-membership.ts +40 -72
- package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
- package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
- package/src/runtime/spots/spot-context.ts +3 -3
- package/src/runtime/spots/spot-entry-activation.ts +13 -30
- package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
- package/src/runtime/spots/spot-manager-public.ts +21 -17
- package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
- package/src/runtime/spots/spot-node-runtime-manager.ts +136 -125
- package/src/runtime/spots/spot-outbound.ts +45 -23
- package/src/runtime/spots/spot-remote-codec.ts +7 -3
- package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
- package/src/runtime/spots/spot-route-replies.ts +6 -4
- package/src/runtime/spots/spot-routed-actor-admission.ts +13 -26
- package/src/runtime/spots/spot-routed-frame-dispatch.ts +2 -3
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
- package/src/runtime/spots/spot-runtime-ports.ts +5 -27
- package/src/runtime/spots/spot-serial-executor.ts +2 -2
- package/src/runtime/spots/spot-serial-turn-executor.ts +112 -11
- package/src/runtime/spots/spot-timer.ts +3 -2
- package/src/runtime/streams/actor-session-binding-registry.ts +179 -269
- package/src/runtime/streams/actor-session-binding-runtime-owner.ts +0 -8
- package/src/runtime/streams/bound-actor-relay-sender.ts +89 -43
- package/src/runtime/streams/bound-session-service.ts +21 -1
- package/src/runtime/streams/index.ts +76 -64
- package/src/runtime/streams/managed-stream.ts +29 -10
- package/src/runtime/streams/native-fallback-bound-session.ts +1 -3
- package/src/runtime/streams/protocol.ts +34 -88
- package/src/runtime/streams/session-actor-coordinator.ts +17 -5
- package/src/runtime/streams/session-calls.ts +6 -5
- package/src/runtime/streams/session-context.ts +54 -10
- package/src/runtime/streams/session-requests.ts +2 -1
- package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
- package/src/runtime/streams/stream-frame-factory.ts +2 -3
- package/src/runtime/streams/stream-session-runtime.ts +57 -59
- package/src/runtime/workers/index.ts +13 -12
- package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
- package/dist/runtime/actors/post-commit-actor-location.js +0 -72
- package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
- package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
- package/src/runtime/actors/post-commit-actor-location.ts +0 -121
- package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export interface OperationClock {
|
|
2
|
-
|
|
3
|
-
clearTimeout(handle: unknown): void;
|
|
2
|
+
now(): number;
|
|
4
3
|
}
|
|
5
4
|
|
|
6
5
|
export class OperationTimeoutError extends Error {
|
|
@@ -26,32 +25,26 @@ export interface PendingOperation<T> {
|
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
interface Entry<T> {
|
|
29
|
-
readonly
|
|
28
|
+
readonly deadlineMs?: number;
|
|
30
29
|
readonly resolve: (value: T | PromiseLike<T>) => void;
|
|
31
30
|
readonly reject: (reason: unknown) => void;
|
|
32
|
-
timer?: unknown;
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
const systemClock: OperationClock = {
|
|
36
|
-
|
|
37
|
-
// A request promise is live work. Raw RouteMesh polling deliberately
|
|
38
|
-
// uses unref'ed timers, so this deadline is the handle that keeps a
|
|
39
|
-
// submit() caller alive until a reply, cancellation, or deadline settles.
|
|
40
|
-
return setTimeout(callback, delayMs);
|
|
41
|
-
},
|
|
42
|
-
clearTimeout(handle) {
|
|
43
|
-
clearTimeout(handle as NodeJS.Timeout);
|
|
44
|
-
}
|
|
34
|
+
now: () => performance.now()
|
|
45
35
|
};
|
|
46
36
|
|
|
47
37
|
/** Owns request completion so reply, timeout, cancellation, and shutdown race safely. */
|
|
48
38
|
export class OperationRegistry<T> {
|
|
49
39
|
private readonly entries = new Map<bigint, Entry<T>>();
|
|
50
40
|
private nextId = 1n;
|
|
51
|
-
private
|
|
41
|
+
private deadlineCursor?: MapIterator<[bigint, Entry<T>]>;
|
|
52
42
|
private closed = false;
|
|
53
43
|
|
|
54
|
-
constructor(
|
|
44
|
+
constructor(
|
|
45
|
+
private readonly clock: OperationClock = systemClock,
|
|
46
|
+
private readonly onPendingChanged?: () => void
|
|
47
|
+
) {}
|
|
55
48
|
|
|
56
49
|
register(
|
|
57
50
|
timeoutMs: number,
|
|
@@ -62,23 +55,19 @@ export class OperationRegistry<T> {
|
|
|
62
55
|
throw new RangeError('timeoutMs must be a non-negative finite number.');
|
|
63
56
|
}
|
|
64
57
|
const id = this.nextId++;
|
|
65
|
-
const generation = this.generation;
|
|
66
58
|
let resolve!: Entry<T>['resolve'];
|
|
67
59
|
let reject!: Entry<T>['reject'];
|
|
68
60
|
const promise = new Promise<T>((onResolve, onReject) => {
|
|
69
61
|
resolve = onResolve;
|
|
70
62
|
reject = onReject;
|
|
71
63
|
});
|
|
72
|
-
const entry: Entry<T> = {
|
|
64
|
+
const entry: Entry<T> = {
|
|
65
|
+
deadlineMs: timeoutOwner === 'registry' ? this.clock.now() + timeoutMs : undefined,
|
|
66
|
+
resolve,
|
|
67
|
+
reject
|
|
68
|
+
};
|
|
73
69
|
this.entries.set(id, entry);
|
|
74
|
-
|
|
75
|
-
// identity and cancellation here without racing that decision with a timer.
|
|
76
|
-
if (timeoutOwner === 'registry') {
|
|
77
|
-
entry.timer = this.clock.setTimeout(
|
|
78
|
-
() => this.rejectIfCurrent(id, generation, new OperationTimeoutError(id)),
|
|
79
|
-
timeoutMs
|
|
80
|
-
);
|
|
81
|
-
}
|
|
70
|
+
if (this.entries.size === 1) this.onPendingChanged?.();
|
|
82
71
|
return { id, promise };
|
|
83
72
|
}
|
|
84
73
|
|
|
@@ -90,10 +79,6 @@ export class OperationRegistry<T> {
|
|
|
90
79
|
}
|
|
91
80
|
|
|
92
81
|
fail(id: bigint, reason: unknown): boolean {
|
|
93
|
-
return this.failCore(id, reason);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
private failCore(id: bigint, reason: unknown): boolean {
|
|
97
82
|
const entry = this.take(id);
|
|
98
83
|
if (entry === undefined) return false;
|
|
99
84
|
entry.reject(reason);
|
|
@@ -101,7 +86,7 @@ export class OperationRegistry<T> {
|
|
|
101
86
|
}
|
|
102
87
|
|
|
103
88
|
cancel(id: bigint, message?: string): boolean {
|
|
104
|
-
return this.
|
|
89
|
+
return this.fail(id, new OperationCancelledError(id, message));
|
|
105
90
|
}
|
|
106
91
|
|
|
107
92
|
isPending(id: bigint): boolean {
|
|
@@ -111,38 +96,36 @@ export class OperationRegistry<T> {
|
|
|
111
96
|
close(reason = 'Operation registry closed.'): void {
|
|
112
97
|
if (this.closed) return;
|
|
113
98
|
this.closed = true;
|
|
114
|
-
this.
|
|
115
|
-
|
|
116
|
-
this.entries.clear();
|
|
117
|
-
for (const [, entry] of pending) this.clearTimer(entry);
|
|
118
|
-
for (const [id, entry] of pending) {
|
|
119
|
-
entry.reject(new OperationCancelledError(id, reason));
|
|
120
|
-
}
|
|
99
|
+
for (const id of this.entries.keys()) this.cancel(id, reason);
|
|
100
|
+
this.deadlineCursor = undefined;
|
|
121
101
|
}
|
|
122
102
|
|
|
123
103
|
get size(): number {
|
|
124
104
|
return this.entries.size;
|
|
125
105
|
}
|
|
126
106
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
107
|
+
expire(nowMs: number, turnDeadlineMs: number): number {
|
|
108
|
+
let expired = 0;
|
|
109
|
+
while (this.clock.now() < turnDeadlineMs) {
|
|
110
|
+
this.deadlineCursor ??= this.entries.entries();
|
|
111
|
+
const current = this.deadlineCursor.next();
|
|
112
|
+
if (current.done === true) {
|
|
113
|
+
this.deadlineCursor = undefined;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
const [id, entry] = current.value;
|
|
117
|
+
if (entry.deadlineMs !== undefined && entry.deadlineMs <= nowMs) {
|
|
118
|
+
if (this.fail(id, new OperationTimeoutError(id))) expired++;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return expired;
|
|
133
122
|
}
|
|
134
123
|
|
|
135
124
|
private take(id: bigint): Entry<T> | undefined {
|
|
136
125
|
const entry = this.entries.get(id);
|
|
137
126
|
if (entry === undefined) return undefined;
|
|
138
127
|
this.entries.delete(id);
|
|
139
|
-
this.
|
|
128
|
+
if (this.entries.size === 0) this.onPendingChanged?.();
|
|
140
129
|
return entry;
|
|
141
130
|
}
|
|
142
|
-
|
|
143
|
-
private clearTimer(entry: Entry<T>): void {
|
|
144
|
-
if (entry.timer === undefined) return;
|
|
145
|
-
this.clock.clearTimeout(entry.timer);
|
|
146
|
-
entry.timer = undefined;
|
|
147
|
-
}
|
|
148
131
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { constants as osConstants } from 'node:os';
|
|
2
|
+
import { ApplicationIngressRecordOwner } from '../application-jobs/application-ingress-record-owner';
|
|
3
|
+
import type {
|
|
4
|
+
ApplicationJobPermitPort,
|
|
5
|
+
ApplicationJobQueuePort
|
|
6
|
+
} from '../application-jobs/contracts';
|
|
1
7
|
import type {
|
|
2
8
|
ZLinkRawBindingPort,
|
|
3
9
|
ZLinkRawHostPort,
|
|
@@ -5,23 +11,26 @@ import type {
|
|
|
5
11
|
ZLinkRawRouterPort
|
|
6
12
|
} from '../backend/raw-binding-port';
|
|
7
13
|
import { RequestResult, SubmitResult } from '../backend/runtime-values';
|
|
8
|
-
import
|
|
9
|
-
ApplicationJobPermitPort,
|
|
10
|
-
ApplicationJobQueuePort
|
|
11
|
-
} from '../application-jobs/contracts';
|
|
12
|
-
import { ApplicationIngressRecordOwner } from '../application-jobs/application-ingress-record-owner';
|
|
14
|
+
import { enumWireRejectReason } from '../protocol/service_wire_codec.generated';
|
|
13
15
|
import { OperationRegistry, type PendingOperation } from './operation-registry';
|
|
14
16
|
import { ServiceLivenessRegistry, type ServiceLivenessTick } from './service-liveness-registry';
|
|
15
17
|
import { ServiceMailbox, type ServiceMailboxRecord } from './service-mailbox';
|
|
16
18
|
import {
|
|
17
|
-
ServiceTopologyRegistry,
|
|
18
19
|
sameServiceNodeDescriptor,
|
|
20
|
+
ServiceTopologyRegistry,
|
|
19
21
|
validateDescriptor,
|
|
20
22
|
type AdmittedServicePeer,
|
|
21
23
|
type PeerAdmissionResult,
|
|
22
|
-
type
|
|
23
|
-
type
|
|
24
|
+
type ServiceNodeDescriptor,
|
|
25
|
+
type ServicePeerAdmissionExpectation
|
|
24
26
|
} from './service-topology-registry';
|
|
27
|
+
import { createServiceWireCodec } from './service-wire-codec';
|
|
28
|
+
import {
|
|
29
|
+
SERVICE_WIRE_MAGIC,
|
|
30
|
+
SERVICE_WIRE_MAJOR,
|
|
31
|
+
ServiceWireCommand,
|
|
32
|
+
ServiceWireFrameworkErrorCode
|
|
33
|
+
} from './service-wire-constants.generated';
|
|
25
34
|
import {
|
|
26
35
|
decodeApplicationPayloadView,
|
|
27
36
|
decodeChannelRequestHeader,
|
|
@@ -40,14 +49,11 @@ import {
|
|
|
40
49
|
encodeReplyHeader,
|
|
41
50
|
encodeRouteMeshAdmission,
|
|
42
51
|
M6aServiceWireCommand,
|
|
43
|
-
|
|
44
|
-
|
|
52
|
+
ServiceWireProtocolError,
|
|
53
|
+
type ServiceApplicationPayload
|
|
45
54
|
} from './service-wire-m6a-codec';
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
ServiceWireCommand,
|
|
49
|
-
ServiceWireFrameworkErrorCode
|
|
50
|
-
} from './service-wire-constants.generated';
|
|
55
|
+
|
|
56
|
+
const nativeErrnoValues = osConstants.errno;
|
|
51
57
|
|
|
52
58
|
export type RawServicePumpResult =
|
|
53
59
|
'noData' | 'infrastructure' | 'application' | 'dropped' | 'protocolError';
|
|
@@ -93,6 +99,7 @@ export type RawServiceIngressHandler = (
|
|
|
93
99
|
) => RawServicePumpResult | undefined | Promise<RawServicePumpResult | undefined>;
|
|
94
100
|
|
|
95
101
|
export interface RawServiceMeshRuntimeOptions {
|
|
102
|
+
readonly onPendingOperationsChanged?: () => void;
|
|
96
103
|
readonly descriptor: ServiceNodeDescriptor;
|
|
97
104
|
readonly resolveAdvertisedEndpoint?: (boundEndpoint: string) => string;
|
|
98
105
|
readonly probeIntervalMs?: number;
|
|
@@ -118,11 +125,15 @@ export interface RawServiceMeshRuntimeOptions {
|
|
|
118
125
|
|
|
119
126
|
// Framework error code 13 (RequestTargetNotFound) is encoded as 14 on a
|
|
120
127
|
// RequestResult.NotFound reply. Boundary transport results keep failureCode 0.
|
|
121
|
-
const
|
|
128
|
+
const RAW_MESH_RECEIVE_RECORD_BUDGET = 64;
|
|
129
|
+
const RAW_MESH_RECEIVE_BYTE_BUDGET = 4 * 1024 * 1024;
|
|
130
|
+
export const RAW_MESH_RECEIVE_TIME_BUDGET_MS = 2;
|
|
131
|
+
|
|
132
|
+
const REQUEST_TARGET_NOT_FOUND_FAILURE_CODE = ServiceWireFrameworkErrorCode.requestTargetNotFound;
|
|
122
133
|
|
|
123
134
|
const livenessCodec = createServiceWireCodec({
|
|
124
|
-
magic:
|
|
125
|
-
major:
|
|
135
|
+
magic: SERVICE_WIRE_MAGIC,
|
|
136
|
+
major: SERVICE_WIRE_MAJOR,
|
|
126
137
|
commands: M6aServiceWireCommand
|
|
127
138
|
});
|
|
128
139
|
|
|
@@ -135,7 +146,7 @@ export class RawServiceMeshRuntime {
|
|
|
135
146
|
readonly mailbox: ServiceMailbox;
|
|
136
147
|
readonly liveness: ServiceLivenessRegistry;
|
|
137
148
|
|
|
138
|
-
private readonly operations
|
|
149
|
+
private readonly operations: OperationRegistry<RawServiceRequestResult>;
|
|
139
150
|
private readonly expectedPeers = new Map<
|
|
140
151
|
string,
|
|
141
152
|
{
|
|
@@ -144,6 +155,7 @@ export class RawServiceMeshRuntime {
|
|
|
144
155
|
readonly endpoint?: string;
|
|
145
156
|
readonly securityIdentity?: string;
|
|
146
157
|
readonly lifecycleGeneration?: bigint;
|
|
158
|
+
helloSubmittedGeneration?: bigint;
|
|
147
159
|
}
|
|
148
160
|
>();
|
|
149
161
|
private readonly endpointOnlyPeers = new Set<string>();
|
|
@@ -170,6 +182,7 @@ export class RawServiceMeshRuntime {
|
|
|
170
182
|
private closed = false;
|
|
171
183
|
|
|
172
184
|
constructor(options: RawServiceMeshRuntimeOptions) {
|
|
185
|
+
this.operations = new OperationRegistry(undefined, options.onPendingOperationsChanged);
|
|
173
186
|
this.descriptor = options.descriptor;
|
|
174
187
|
this.topology = new ServiceTopologyRegistry(options.descriptor);
|
|
175
188
|
this.mailbox = new ServiceMailbox(options.onMailboxReady);
|
|
@@ -224,13 +237,16 @@ export class RawServiceMeshRuntime {
|
|
|
224
237
|
|
|
225
238
|
connectPeer(endpoint: string, expected: ServiceNodeDescriptor): void {
|
|
226
239
|
this.requireStarted().connectToRoutingId(expected.nodeRoutingId, endpoint);
|
|
227
|
-
this.expectedPeers.set(
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
240
|
+
this.expectedPeers.set(
|
|
241
|
+
expected.nodeRoutingId,
|
|
242
|
+
Object.assign(this.expectedPeers.get(expected.nodeRoutingId) ?? {}, {
|
|
243
|
+
meshName: expected.meshName,
|
|
244
|
+
nodeRoutingId: expected.nodeRoutingId,
|
|
245
|
+
endpoint,
|
|
246
|
+
securityIdentity: expected.securityIdentity,
|
|
247
|
+
lifecycleGeneration: expected.lifecycleGeneration
|
|
248
|
+
})
|
|
249
|
+
);
|
|
234
250
|
}
|
|
235
251
|
|
|
236
252
|
connectPeerByRoutingId(
|
|
@@ -240,13 +256,16 @@ export class RawServiceMeshRuntime {
|
|
|
240
256
|
lifecycleGeneration?: bigint
|
|
241
257
|
): void {
|
|
242
258
|
this.requireStarted().connectToRoutingId(nodeRoutingId, endpoint);
|
|
243
|
-
this.expectedPeers.set(
|
|
244
|
-
meshName: this.topology.localDescriptor().meshName,
|
|
259
|
+
this.expectedPeers.set(
|
|
245
260
|
nodeRoutingId,
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
261
|
+
Object.assign(this.expectedPeers.get(nodeRoutingId) ?? {}, {
|
|
262
|
+
meshName: this.topology.localDescriptor().meshName,
|
|
263
|
+
nodeRoutingId,
|
|
264
|
+
endpoint,
|
|
265
|
+
securityIdentity,
|
|
266
|
+
lifecycleGeneration
|
|
267
|
+
})
|
|
268
|
+
);
|
|
250
269
|
}
|
|
251
270
|
|
|
252
271
|
expectPeerByRoutingId(
|
|
@@ -255,13 +274,16 @@ export class RawServiceMeshRuntime {
|
|
|
255
274
|
securityIdentity?: string,
|
|
256
275
|
lifecycleGeneration?: bigint
|
|
257
276
|
): void {
|
|
258
|
-
this.expectedPeers.set(
|
|
259
|
-
meshName: this.topology.localDescriptor().meshName,
|
|
277
|
+
this.expectedPeers.set(
|
|
260
278
|
nodeRoutingId,
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
279
|
+
Object.assign(this.expectedPeers.get(nodeRoutingId) ?? {}, {
|
|
280
|
+
meshName: this.topology.localDescriptor().meshName,
|
|
281
|
+
nodeRoutingId,
|
|
282
|
+
endpoint,
|
|
283
|
+
securityIdentity,
|
|
284
|
+
lifecycleGeneration
|
|
285
|
+
})
|
|
286
|
+
);
|
|
265
287
|
}
|
|
266
288
|
|
|
267
289
|
connectPeerEndpoint(endpoint: string): void {
|
|
@@ -349,11 +371,25 @@ export class RawServiceMeshRuntime {
|
|
|
349
371
|
}
|
|
350
372
|
|
|
351
373
|
async announcePeer(nodeRoutingId: string): Promise<boolean> {
|
|
352
|
-
|
|
374
|
+
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
375
|
+
const generation = this.selectedRoutes.get(nodeRoutingId);
|
|
376
|
+
if (
|
|
377
|
+
expected === undefined ||
|
|
378
|
+
generation === undefined ||
|
|
379
|
+
expected.helloSubmittedGeneration === generation ||
|
|
380
|
+
this.peerAdmissionSealed?.() === true
|
|
381
|
+
)
|
|
353
382
|
return false;
|
|
354
|
-
|
|
383
|
+
const accepted = await this.send(nodeRoutingId, [
|
|
355
384
|
encodeRouteMeshAdmission(M6aServiceWireCommand.hello, this.topology.localDescriptor())
|
|
356
385
|
]);
|
|
386
|
+
if (
|
|
387
|
+
accepted &&
|
|
388
|
+
this.expectedPeers.get(nodeRoutingId) === expected &&
|
|
389
|
+
this.selectedRoutes.get(nodeRoutingId) === generation
|
|
390
|
+
)
|
|
391
|
+
expected.helloSubmittedGeneration = generation;
|
|
392
|
+
return accepted;
|
|
357
393
|
}
|
|
358
394
|
|
|
359
395
|
isPeerRouteReady(nodeRoutingId: string, lifecycleGeneration?: bigint): boolean {
|
|
@@ -371,11 +407,6 @@ export class RawServiceMeshRuntime {
|
|
|
371
407
|
async announceExpectedPeers(): Promise<number> {
|
|
372
408
|
let accepted = 0;
|
|
373
409
|
for (const nodeRoutingId of this.expectedPeers.keys()) {
|
|
374
|
-
// Admission is a one-time fence for the current selected route.
|
|
375
|
-
// Re-sending Hello after the peer is admitted would re-run admission on
|
|
376
|
-
// every poll and reset the liveness record before application traffic
|
|
377
|
-
// can use the route. A peer whose selected route ended is removed by the
|
|
378
|
-
// route observer and remains eligible for the next admission attempt.
|
|
379
410
|
if (this.topology.peer(nodeRoutingId) !== undefined) continue;
|
|
380
411
|
if (await this.announcePeer(nodeRoutingId)) accepted++;
|
|
381
412
|
}
|
|
@@ -419,7 +450,6 @@ export class RawServiceMeshRuntime {
|
|
|
419
450
|
for (const peer of this.topology.peers()) {
|
|
420
451
|
await this.send(peer.descriptor.nodeRoutingId, [update]);
|
|
421
452
|
}
|
|
422
|
-
await this.announceExpectedPeers();
|
|
423
453
|
}
|
|
424
454
|
|
|
425
455
|
replaceDiscoveredNotRequired(descriptors: readonly ServiceNodeDescriptor[]): void {
|
|
@@ -449,23 +479,6 @@ export class RawServiceMeshRuntime {
|
|
|
449
479
|
if (selection.kind !== 'selected') return selection.submitResult;
|
|
450
480
|
const selected = selection.peer;
|
|
451
481
|
const applicationFrame = this.applicationFrame(payload);
|
|
452
|
-
if (selected.descriptor.nodeRoutingId === this.descriptor.nodeRoutingId) {
|
|
453
|
-
const applicationJobOwner = await this.reserveLocalIngress();
|
|
454
|
-
try {
|
|
455
|
-
const applicationJob = await applicationJobOwner.acquire('application');
|
|
456
|
-
const accepted = this.mailbox.tryEnqueue({
|
|
457
|
-
owner: `channel:${channelName}`,
|
|
458
|
-
domain: 'application',
|
|
459
|
-
parts: [encodeChannelSendHeader(channelName), applicationFrame],
|
|
460
|
-
sourceRoutingId: this.descriptor.nodeRoutingId,
|
|
461
|
-
applicationJob
|
|
462
|
-
});
|
|
463
|
-
if (!accepted) applicationJob.close();
|
|
464
|
-
return accepted ? SubmitResult.Ok : SubmitResult.NotAdmitted;
|
|
465
|
-
} finally {
|
|
466
|
-
applicationJobOwner.close();
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
482
|
return (await this.send(selected.descriptor.nodeRoutingId, [
|
|
470
483
|
encodeChannelSendHeader(channelName),
|
|
471
484
|
applicationFrame
|
|
@@ -503,7 +516,7 @@ export class RawServiceMeshRuntime {
|
|
|
503
516
|
|
|
504
517
|
private selectChannelTarget(channelName: string): RawServiceChannelTargetSelection {
|
|
505
518
|
const selected = this.topology.selectChannel(channelName, (peer) =>
|
|
506
|
-
this.
|
|
519
|
+
this.isPeerRouteReady(peer.descriptor.nodeRoutingId)
|
|
507
520
|
);
|
|
508
521
|
if (selected !== undefined) return { kind: 'selected', peer: selected };
|
|
509
522
|
return this.topology.hasKnownChannelTarget(channelName)
|
|
@@ -522,10 +535,6 @@ export class RawServiceMeshRuntime {
|
|
|
522
535
|
};
|
|
523
536
|
}
|
|
524
537
|
|
|
525
|
-
private isLocalOrReadyPeer(nodeRoutingId: string): boolean {
|
|
526
|
-
return nodeRoutingId === this.descriptor.nodeRoutingId || this.isPeerRouteReady(nodeRoutingId);
|
|
527
|
-
}
|
|
528
|
-
|
|
529
538
|
setServiceIngress(handler: RawServiceIngressHandler): void {
|
|
530
539
|
if (this.serviceIngress !== undefined && this.serviceIngress !== handler) {
|
|
531
540
|
throw new Error('Raw service ingress is already registered.');
|
|
@@ -600,20 +609,20 @@ export class RawServiceMeshRuntime {
|
|
|
600
609
|
return this.receiveOne(nowMs, observe);
|
|
601
610
|
}
|
|
602
611
|
|
|
603
|
-
setReadableHandler(handler: () => void): void {
|
|
612
|
+
setReadableHandler(handler: (receiveReady: boolean, routeReady: boolean) => void): void {
|
|
604
613
|
this.requireStarted().setReadableHandler(handler);
|
|
605
614
|
}
|
|
606
615
|
|
|
607
616
|
/** Returns whether a receive budget ended before no-data; idle ticks only maintain peers. */
|
|
608
|
-
async pumpBatch(receiveReady = true): Promise<boolean> {
|
|
609
|
-
await this.observeSelectedRoutes();
|
|
617
|
+
async pumpBatch(receiveReady = true, routeReady = false): Promise<boolean> {
|
|
618
|
+
if (routeReady) await this.observeSelectedRoutes();
|
|
610
619
|
const startedAtMs = performance.now();
|
|
611
620
|
let messages = 0;
|
|
612
621
|
let bytes = 0;
|
|
613
622
|
const observe: RawServicePumpObserver = (_source, byteCount) => {
|
|
614
623
|
bytes += byteCount;
|
|
615
624
|
};
|
|
616
|
-
while (receiveReady && messages <
|
|
625
|
+
while (receiveReady && messages < RAW_MESH_RECEIVE_RECORD_BUDGET && !this.closed) {
|
|
617
626
|
const result = await this.receiveOne(performance.now(), observe);
|
|
618
627
|
if (result === 'noData') {
|
|
619
628
|
receiveReady = false;
|
|
@@ -622,7 +631,11 @@ export class RawServiceMeshRuntime {
|
|
|
622
631
|
messages += 1;
|
|
623
632
|
// Core owns the per-peer fair-queue cursor. The Framework limit bounds
|
|
624
633
|
// the entire round, so changing peers does not renew its byte/count budget.
|
|
625
|
-
if (
|
|
634
|
+
if (
|
|
635
|
+
bytes >= RAW_MESH_RECEIVE_BYTE_BUDGET ||
|
|
636
|
+
performance.now() - startedAtMs >= RAW_MESH_RECEIVE_TIME_BUDGET_MS
|
|
637
|
+
)
|
|
638
|
+
break;
|
|
626
639
|
}
|
|
627
640
|
if (!this.closed) {
|
|
628
641
|
await this.announceExpectedPeers();
|
|
@@ -758,7 +771,9 @@ export class RawServiceMeshRuntime {
|
|
|
758
771
|
(expected.meshName !== descriptor.meshName ||
|
|
759
772
|
expected.nodeRoutingId !== descriptor.nodeRoutingId)
|
|
760
773
|
) {
|
|
761
|
-
await this.send(received.sourceRid, [
|
|
774
|
+
await this.send(received.sourceRid, [
|
|
775
|
+
encodeReject(enumWireRejectReason('identityMismatch'))
|
|
776
|
+
]);
|
|
762
777
|
return 'infrastructure';
|
|
763
778
|
}
|
|
764
779
|
const result = this.admitPeer(
|
|
@@ -798,23 +813,7 @@ export class RawServiceMeshRuntime {
|
|
|
798
813
|
}
|
|
799
814
|
if (header.command === M6aServiceWireCommand.reject) {
|
|
800
815
|
if (received.parts.length !== 1) return 'protocolError';
|
|
801
|
-
|
|
802
|
-
// Keep an already admitted peer: a reject of an earlier Hello on the
|
|
803
|
-
// same selected route does not end the admission that succeeded.
|
|
804
|
-
if (reason === 4 && this.topology.peer(received.sourceRid) === undefined) {
|
|
805
|
-
const expected = this.expectedPeers.get(received.sourceRid);
|
|
806
|
-
const local = this.topology.localDescriptor();
|
|
807
|
-
this.topology.markNotRequired({
|
|
808
|
-
...local,
|
|
809
|
-
nodeRoutingId: received.sourceRid,
|
|
810
|
-
lifecycleGeneration: 1n,
|
|
811
|
-
descriptorRevision: 1n,
|
|
812
|
-
advertisedEndpoint: expected?.endpoint ?? local.advertisedEndpoint,
|
|
813
|
-
channels: [],
|
|
814
|
-
objectRole: 'client'
|
|
815
|
-
});
|
|
816
|
-
this.retireNotRequiredExpectedPeer(received.sourceRid);
|
|
817
|
-
}
|
|
816
|
+
decodeReject(received.parts[0]!);
|
|
818
817
|
return 'infrastructure';
|
|
819
818
|
}
|
|
820
819
|
const peer = this.topology.peer(received.sourceRid);
|
|
@@ -945,6 +944,14 @@ export class RawServiceMeshRuntime {
|
|
|
945
944
|
}
|
|
946
945
|
}
|
|
947
946
|
|
|
947
|
+
expireOperations(nowMs: number, turnDeadlineMs: number): number {
|
|
948
|
+
return this.operations.expire(nowMs, turnDeadlineMs);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
get pendingOperationCount(): number {
|
|
952
|
+
return this.operations.size;
|
|
953
|
+
}
|
|
954
|
+
|
|
948
955
|
async tickLiveness(nowMs = performance.now()): Promise<ServiceLivenessTick> {
|
|
949
956
|
const result = this.liveness.tick(nowMs);
|
|
950
957
|
this.requireStarted();
|
|
@@ -982,6 +989,8 @@ export class RawServiceMeshRuntime {
|
|
|
982
989
|
for (const [nodeRoutingId, generation] of this.selectedRoutes) {
|
|
983
990
|
if (observed.get(nodeRoutingId) === generation) continue;
|
|
984
991
|
changes++;
|
|
992
|
+
const expected = this.expectedPeers.get(nodeRoutingId);
|
|
993
|
+
if (expected !== undefined) delete expected.helloSubmittedGeneration;
|
|
985
994
|
const peer = this.topology.peer(nodeRoutingId);
|
|
986
995
|
if (peer !== undefined && peer.connectionId === routeConnectionId(generation)) {
|
|
987
996
|
this.removePeer(peer);
|
|
@@ -1001,7 +1010,6 @@ export class RawServiceMeshRuntime {
|
|
|
1001
1010
|
|
|
1002
1011
|
close(): void {
|
|
1003
1012
|
if (this.closed) return;
|
|
1004
|
-
this.closed = true;
|
|
1005
1013
|
this.applicationJobStop.abort(
|
|
1006
1014
|
new Error('Raw service runtime application job admission stopped.')
|
|
1007
1015
|
);
|
|
@@ -1013,9 +1021,10 @@ export class RawServiceMeshRuntime {
|
|
|
1013
1021
|
this.applicationJobQueue.unregisterReceiveFlowTarget?.(router);
|
|
1014
1022
|
}
|
|
1015
1023
|
const host = this.host;
|
|
1024
|
+
if (host !== undefined) host.close();
|
|
1016
1025
|
this.router = undefined;
|
|
1017
1026
|
this.host = undefined;
|
|
1018
|
-
|
|
1027
|
+
this.closed = true;
|
|
1019
1028
|
}
|
|
1020
1029
|
|
|
1021
1030
|
private requestToTarget(
|
|
@@ -1046,14 +1055,11 @@ export class RawServiceMeshRuntime {
|
|
|
1046
1055
|
for (;;) {
|
|
1047
1056
|
const alternate = this.topology.selectChannel(channelName, (peer) => {
|
|
1048
1057
|
const candidate = peer.descriptor.nodeRoutingId;
|
|
1049
|
-
return !excludedTargets.has(candidate) && this.
|
|
1058
|
+
return !excludedTargets.has(candidate) && this.isPeerRouteReady(candidate);
|
|
1050
1059
|
});
|
|
1051
1060
|
if (alternate === undefined) break;
|
|
1052
1061
|
selectedTargetNodeRoutingId = alternate.descriptor.nodeRoutingId;
|
|
1053
|
-
if (
|
|
1054
|
-
selectedTargetNodeRoutingId === this.descriptor.nodeRoutingId ||
|
|
1055
|
-
this.isPeerRouteReady(selectedTargetNodeRoutingId)
|
|
1056
|
-
) {
|
|
1062
|
+
if (this.isPeerRouteReady(selectedTargetNodeRoutingId)) {
|
|
1057
1063
|
break;
|
|
1058
1064
|
}
|
|
1059
1065
|
excludedTargets.add(selectedTargetNodeRoutingId);
|
|
@@ -1077,10 +1083,7 @@ export class RawServiceMeshRuntime {
|
|
|
1077
1083
|
return;
|
|
1078
1084
|
}
|
|
1079
1085
|
const accepted = this.mailbox.tryEnqueue({
|
|
1080
|
-
owner:
|
|
1081
|
-
channelName === undefined
|
|
1082
|
-
? `node:${this.descriptor.nodeRoutingId}`
|
|
1083
|
-
: `channel:${channelName}`,
|
|
1086
|
+
owner: `node:${this.descriptor.nodeRoutingId}`,
|
|
1084
1087
|
domain: 'application',
|
|
1085
1088
|
parts,
|
|
1086
1089
|
sourceRoutingId: this.descriptor.nodeRoutingId,
|
|
@@ -1300,7 +1303,7 @@ function isAlreadyDisconnectedError(error: unknown): boolean {
|
|
|
1300
1303
|
if (typeof error !== 'object' || error === null || !('nativeErrno' in error)) {
|
|
1301
1304
|
return false;
|
|
1302
1305
|
}
|
|
1303
|
-
return (error as { readonly nativeErrno?: unknown }).nativeErrno ===
|
|
1306
|
+
return (error as { readonly nativeErrno?: unknown }).nativeErrno === nativeErrnoValues.ENOENT;
|
|
1304
1307
|
}
|
|
1305
1308
|
|
|
1306
1309
|
/**
|
|
@@ -1378,17 +1381,13 @@ function immutableDescriptorMismatch(
|
|
|
1378
1381
|
return undefined;
|
|
1379
1382
|
}
|
|
1380
1383
|
|
|
1381
|
-
function admissionReason(result: PeerAdmissionResult): number {
|
|
1384
|
+
function admissionReason(result: Exclude<PeerAdmissionResult, 'admitted' | 'notRequired'>): number {
|
|
1382
1385
|
switch (result) {
|
|
1383
1386
|
case 'meshMismatch':
|
|
1384
|
-
return
|
|
1387
|
+
return enumWireRejectReason('topologyMismatch');
|
|
1385
1388
|
case 'staleDescriptor':
|
|
1386
|
-
return
|
|
1389
|
+
return enumWireRejectReason('descriptorRevisionStale');
|
|
1387
1390
|
case 'invalidDescriptor':
|
|
1388
|
-
return
|
|
1389
|
-
case 'notRequired':
|
|
1390
|
-
return 4;
|
|
1391
|
-
case 'admitted':
|
|
1392
|
-
return 1;
|
|
1391
|
+
return enumWireRejectReason('invalidDescriptor');
|
|
1393
1392
|
}
|
|
1394
1393
|
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import { ZLinkFrameworkRuntimeState } from '../../contracts';
|
|
1
|
+
import { ZLinkFrameworkRuntimeState, ZLinkTopologyState } from '../../contracts';
|
|
2
|
+
|
|
3
|
+
export function runtimeObservationIsTerminal(state: ZLinkFrameworkRuntimeState): boolean {
|
|
4
|
+
return state === ZLinkFrameworkRuntimeState.Stopped;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function topologyObservationIsTerminal(state: ZLinkTopologyState): boolean {
|
|
8
|
+
return state === ZLinkTopologyState.Stopped || state === ZLinkTopologyState.Failed;
|
|
9
|
+
}
|
|
2
10
|
|
|
3
11
|
export type MaintenanceAdmissionState =
|
|
4
12
|
'preparing' | 'serving' | 'retiring' | 'draining' | 'stopped' | 'error';
|