From 03aac0025d305f96de765d4217ddf4c2d3775f70 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Jun 2026 15:56:26 +0000 Subject: [PATCH] fix(nestsClient): write Ended announce when publisher.close() races registerAnnounceBidi When publisher.close() acquires the gate lock before registerAnnounceBidi, the announce bidi list is empty and no Ended message is sent. Fix by writing Ended + finishing the bidi in registerAnnounceBidi when publisherClosed is already true, mirroring what close() does for bidis it owns at close time. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_015t3bsJruGerz53yafZyp9n --- .../nestsclient/moq/lite/MoqLiteSession.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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 be47b28baa..fa8dfaf59c 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 @@ -1398,6 +1398,20 @@ class MoqLiteSession internal constructor( ) { gate.withLock { if (publisherClosed) { + // publisher.close() raced ahead — write Ended now so + // the relay sees the proper lifecycle close on this bidi. + runCatching { + bidi.write( + MoqLiteCodec.encodeAnnounce( + MoqLiteAnnounce( + status = MoqLiteAnnounceStatus.Ended, + suffix = emittedSuffix, + hops = emptyList(), + ), + version, + ), + ) + } runCatching { bidi.finish() } return }