From 73722d2ad2c9f2351c5cea9bb2d6acc7ea686b46 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 6 May 2026 17:37:19 +0000 Subject: [PATCH] fix(nests): T14 recognise Goaway control type instead of silent FIN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit moq-rs's `Publisher::run` accepts `ControlType::Goaway = 5` as a graceful-shutdown signal that asks the publisher to migrate to a different relay node (`rs/moq-lite/src/lite/publisher.rs`). Our enum only defined Session/Announce/Subscribe/Fetch/Probe; an inbound Goaway bidi fell through `MoqLiteControlType.fromCode` as `null`, hit the unknown-control branch in `handleInboundBidi`, and was FIN'd silently — losing the relay's shutdown notification entirely. Add `Goaway(5L)` to the enum and a dedicated arm in `handleInboundBidi` that logs the event and FINs cleanly. We don't act on the migration request today (no body decode, no preferred-relay failover); the `connectReconnecting*` wrappers' transport-loss reconnect path already recovers from the eventual hard disconnect, so all this arm needs is to surface the relay's intent in logcat instead of swallowing it. Wire body decoding is left as a follow-up. https://claude.ai/code/session_014JfZJHSTvyYYWJbC9VbB47 --- .../nestsclient/moq/lite/MoqLiteMessages.kt | 11 +++++++++++ .../nestsclient/moq/lite/MoqLiteSession.kt | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteMessages.kt b/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteMessages.kt index b55f2e0ee..66e75df97 100644 --- a/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteMessages.kt +++ b/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteMessages.kt @@ -73,6 +73,17 @@ enum class MoqLiteControlType( Subscribe(2L), Fetch(3L), Probe(4L), + + /** + * Graceful relay-shutdown signal. moq-rs's `Publisher::run` accepts + * `ControlType::Goaway = 5` (`rs/moq-lite/src/lite/publisher.rs`) + * to migrate a publisher to a different relay node. We don't act + * on it today — recognising the type code prevents + * [MoqLiteSession.handleInboundBidi] from silently FINing the + * bidi as an unknown control type, which would lose the relay's + * shutdown notification. Wire body decoding is left as a follow-up. + */ + Goaway(5L), ; companion object { diff --git a/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteSession.kt b/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteSession.kt index 961f9cfe9..4b7f3cbe1 100644 --- a/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteSession.kt +++ b/nestsClient/src/commonMain/kotlin/com/vitorpamplona/nestsclient/moq/lite/MoqLiteSession.kt @@ -953,6 +953,25 @@ class MoqLiteSession internal constructor( runCatching { bidi.finish() } dispatched = true } + + MoqLiteControlType.Goaway -> { + // Relay's graceful-shutdown signal — see + // [MoqLiteControlType.Goaway]. We don't + // act on the migration request today + // (no body decode, no preferred-relay + // failover); the `connectReconnecting*` + // wrappers' transport-loss reconnect path + // already handles the eventual hard + // disconnect, so all this arm needs to do + // is recognise the type code and FIN + // cleanly instead of treating it as an + // unknown control. Logged so a relay- + // initiated migration shows up in logcat + // rather than as a mystery silent reconnect. + Log.w("NestRx") { "Goaway received from relay — FIN bidi (no migration handler today)" } + runCatching { bidi.finish() } + dispatched = true + } } } // Post-dispatch chunks are silently discarded —