From e1e2c4f89bb0641ed4e353188078065ea47685b6 Mon Sep 17 00:00:00 2001 From: Stas Shevchenko Date: Thu, 3 Sep 2026 21:22:52 +0200 Subject: [PATCH 1/2] Remove racy waiter from getOrUpdateOpt test --- .../src/test/scala/com/evolution/scache/CacheSpec.scala | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/scache/src/test/scala/com/evolution/scache/CacheSpec.scala b/scache/src/test/scala/com/evolution/scache/CacheSpec.scala index d5c0ae6f..e516be58 100644 --- a/scache/src/test/scala/com/evolution/scache/CacheSpec.scala +++ b/scache/src/test/scala/com/evolution/scache/CacheSpec.scala @@ -458,17 +458,13 @@ class CacheSpec extends AsyncFunSuite with Matchers { for { deferred <- Deferred[IO, Option[Int]] value0 <- cache.getOrUpdateOptEnsure(0) { deferred.get } - value1 <- cache.getOrUpdateOpt(0)(0.some.pure[IO]).startEnsure _ <- deferred.complete(none) value0 <- value0.joinWithNever - value1 <- value1.joinWithNever - _ = value0 shouldEqual none[Int].asRight - _ = value1 shouldEqual none[Int] + _ <- IO { value0 shouldEqual none[Int].asRight } value <- cache.getOrUpdateOpt(0)(0.some.pure[IO]) - _ = value shouldEqual 0.some + _ <- IO { value shouldEqual 0.some } _ <- metrics.expect( metrics.expectedGet(hit = false) -> 2, - metrics.expectedGet(hit = true) -> 1, metrics.expectedLoad(success = true) -> 2, ) } yield {} From 83816ac60df0f474e658d6cb0f9b8a3329826c27 Mon Sep 17 00:00:00 2001 From: Stas Shevchenko Date: Mon, 21 Sep 2026 20:01:26 +0200 Subject: [PATCH 2/2] Make getOrUpdateOpt test fully sequential --- .../test/scala/com/evolution/scache/CacheSpec.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scache/src/test/scala/com/evolution/scache/CacheSpec.scala b/scache/src/test/scala/com/evolution/scache/CacheSpec.scala index e516be58..66b6c1fd 100644 --- a/scache/src/test/scala/com/evolution/scache/CacheSpec.scala +++ b/scache/src/test/scala/com/evolution/scache/CacheSpec.scala @@ -456,15 +456,15 @@ class CacheSpec extends AsyncFunSuite with Matchers { check(s"getOrUpdateOpt: $name") { (cache, metrics) => for { - deferred <- Deferred[IO, Option[Int]] - value0 <- cache.getOrUpdateOptEnsure(0) { deferred.get } - _ <- deferred.complete(none) - value0 <- value0.joinWithNever - _ <- IO { value0 shouldEqual none[Int].asRight } - value <- cache.getOrUpdateOpt(0)(0.some.pure[IO]) + value <- cache.getOrUpdateOpt(0) { none[Int].pure[IO] } + _ <- IO { value shouldEqual none[Int] } + value <- cache.getOrUpdateOpt(0) { 0.some.pure[IO] } + _ <- IO { value shouldEqual 0.some } + value <- cache.getOrUpdateOpt(0) { 1.some.pure[IO] } _ <- IO { value shouldEqual 0.some } _ <- metrics.expect( metrics.expectedGet(hit = false) -> 2, + metrics.expectedGet(hit = true) -> 1, metrics.expectedLoad(success = true) -> 2, ) } yield {}