-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Closed
Description
During research of the previous problem #4395 find out that we have a probability to not properly cancel await in https://github.com/zio/zio/blob/master/streams/shared/src/main/scala/zio/stream/ZStream.scala#L1981
errorSignal.await raceFirst f(a)
Here is simple reproducible scenario, the faster you create & interrupt fibers, the more chance that Canceler will not get fired
testM("joiners should properly clean up") {
(for {
p <- Promise.make[Throwable, Unit]
spawner = ZStream.repeatEffect(ZIO.unit raceFirst p.await).runDrain
_ <- spawner.fork
joinersCount <- Task
.succeed(p.state.get.asInstanceOf[Pending[_, _]].joiners.size)
.tap(_ => p.succeed(()))
.delay(60.seconds)
} yield assert(joinersCount)(isLessThan(2)))
.provideCustomLayer(zio.clock.Clock.live)
}
After debug this piece of code we are able to see such picture, some of fibers got interrupted, but not cleaned up:
Upd. the problem appears when we delegate interruption to another fiber:
for {
p <- Promise.make[Throwable, Unit]
_ <- ( for {
fb <- p.await.fork
_ <- fb.interrupt.fork //<<< If remove this fork and keep just `fb.intterupt`, everything works fine
} yield ()).forever.fork
_ <- p.succeed(()).delay(30.seconds)
} yield ()
Metadata
Metadata
Assignees
Labels
No labels