Skip to content

Commit a4a6bda

Browse files
Implement lock aquiring shenanigans and restore related test
Thanks to armanbilge for the [suggestion](typelevel#4267 (comment))
1 parent 6a63a2c commit a4a6bda

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

std/shared/src/main/scala/cats/effect/std/Hotswap.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package cats.effect.std
1818

1919
import cats.effect.kernel.{Concurrent, Resource}
20+
import cats.effect.kernel.Resource.ExitCase.Succeeded
2021
import cats.syntax.all._
2122

2223
/**
@@ -106,7 +107,13 @@ object Hotswap {
106107
override def swap(next: Resource[F, R]): F[R] =
107108
nes.swap(next.map(_.some)) *> get.use(_.get.pure[F])
108109

109-
override def get: Resource[F, Option[R]] = nes.get
110+
override def get: Resource[F, Option[R]] =
111+
Resource.applyFull[F, Option[R]] { poll =>
112+
poll(nes.get.allocatedCase).flatMap {
113+
case (None, fin) => fin(Succeeded) *> F.pure((None, _ => F.unit))
114+
case (r, fin) => F.pure((r, fin))
115+
}
116+
}
110117

111118
override def clear: F[Unit] = nes.clear
112119
}

tests/shared/src/test/scala/cats/effect/std/HotswapSpec.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,5 +165,15 @@ class HotswapSpec extends BaseSpec { outer =>
165165

166166
TestControl.executeEmbed(go, IORuntimeConfig(1, 2)).replicateA_(1000) must completeAs(())
167167
}
168+
169+
"get should not acquire a lock when there is no resource present" in ticked {
170+
implicit ticker =>
171+
val go = Hotswap.create[IO, Unit].use { hs =>
172+
hs.get.useForever.start *>
173+
IO.sleep(2.seconds) *>
174+
hs.swap(Resource.unit)
175+
}
176+
go must completeAs(())
177+
}
168178
}
169179
}

0 commit comments

Comments
 (0)