From 87baacf635f690aeabee26a4688832137ff65a18 Mon Sep 17 00:00:00 2001 From: Ian Botsford <83236726+ianbotsf@users.noreply.github.com> Date: Fri, 28 Feb 2025 17:11:00 +0000 Subject: [PATCH 1/3] fix: correctly handle sequential calls to `SingleFlightGroup` --- .changes/065e6349-8e2a-403b-b588-067161f260fd.json | 5 +++++ .../smithy/kotlin/runtime/util/SingleFlightGroup.kt | 2 +- .../kotlin/runtime/util/SingleFlightGroupTest.kt | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 .changes/065e6349-8e2a-403b-b588-067161f260fd.json diff --git a/.changes/065e6349-8e2a-403b-b588-067161f260fd.json b/.changes/065e6349-8e2a-403b-b588-067161f260fd.json new file mode 100644 index 0000000000..80a6796004 --- /dev/null +++ b/.changes/065e6349-8e2a-403b-b588-067161f260fd.json @@ -0,0 +1,5 @@ +{ + "id": "065e6349-8e2a-403b-b588-067161f260fd", + "type": "bugfix", + "description": "Correctly handle sequential calls to `SingleFlightGroup`" +} \ No newline at end of file diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/SingleFlightGroup.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/SingleFlightGroup.kt index 6234d20733..b18048c85e 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/SingleFlightGroup.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/SingleFlightGroup.kt @@ -52,6 +52,6 @@ public class SingleFlightGroup { inFlight = deferred mu.unlock() runCatching { block() }.let { deferred.complete(it) } - return deferred.await().getOrThrow() + return deferred.await().also { inFlight = null }.getOrThrow() } } diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SingleFlightGroupTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SingleFlightGroupTest.kt index cfe9d626fb..e1d172fd8a 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SingleFlightGroupTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SingleFlightGroupTest.kt @@ -109,4 +109,14 @@ class SingleFlightGroupTest { } } } + + @Test + fun testSequential() = runTest { + val group = SingleFlightGroup() + val first = group.singleFlight { "Foo" } + assertEquals("Foo", first) + + val second = group.singleFlight { "Bar" } + assertEquals("Bar", second) // Fails; second == "Foo" + } } From 050108487bceda06ce7e483e97f464fb6091abb9 Mon Sep 17 00:00:00 2001 From: Ian Botsford <83236726+ianbotsf@users.noreply.github.com> Date: Fri, 28 Feb 2025 17:52:25 +0000 Subject: [PATCH 2/3] remove now-erroneous comment --- .../aws/smithy/kotlin/runtime/util/SingleFlightGroupTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SingleFlightGroupTest.kt b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SingleFlightGroupTest.kt index e1d172fd8a..f468889d7b 100644 --- a/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SingleFlightGroupTest.kt +++ b/runtime/runtime-core/common/test/aws/smithy/kotlin/runtime/util/SingleFlightGroupTest.kt @@ -117,6 +117,6 @@ class SingleFlightGroupTest { assertEquals("Foo", first) val second = group.singleFlight { "Bar" } - assertEquals("Bar", second) // Fails; second == "Foo" + assertEquals("Bar", second) } } From ee2df40390c8efafb1af089e36c5c654a044d15a Mon Sep 17 00:00:00 2001 From: Ian Botsford <83236726+ianbotsf@users.noreply.github.com> Date: Sat, 1 Mar 2025 00:16:35 +0000 Subject: [PATCH 3/3] Rework fix for SFG --- .../src/aws/smithy/kotlin/runtime/util/SingleFlightGroup.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/SingleFlightGroup.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/SingleFlightGroup.kt index b18048c85e..5f36f3a4ae 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/SingleFlightGroup.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/SingleFlightGroup.kt @@ -30,7 +30,7 @@ public class SingleFlightGroup { public suspend fun singleFlight(block: suspend () -> T): T { mu.lock() val job = inFlight - if (job != null) { + if (job?.isActive == true) { waitCount++ mu.unlock() @@ -52,6 +52,6 @@ public class SingleFlightGroup { inFlight = deferred mu.unlock() runCatching { block() }.let { deferred.complete(it) } - return deferred.await().also { inFlight = null }.getOrThrow() + return deferred.await().getOrThrow() } }