Resource finalization out of order when using with concurrent stream.
It appears that resource finalizer is not being called correctly in order. In this simple example, almost all runs I did, the finalizer gets called before the last .use statement
Version: 3.2.8
import cats.effect.syntax.all.*
import cats.syntax.all.*
import cats.effect.*
import fs2.Stream
object Main extends IOApp.Simple:
val run = Stream
.resource(
Resource.make(IO.println("hello").as(100))(n =>
IO.println(s"goodbye: $n")
)
)
.concurrently(Stream.emits[IO, Int](1 to 10).evalMap(IO.println))
.compile
.resource
.lastOrError
.use(x => IO.println(s"From use: $x"))
Output:
1
hello
2
goodbye: 100
3
4
From use: 100
5
https://scastie.scala-lang.org/NmxxGQjXREyyA3RflV9nqA
Initial guess is that this is example of badly interacting features -- concurrently and .compile.resource. That is, concurrently introduces its own root scope which results in the scope from Stream.resource no longer being a root scope, and hence not having its lifetime extended to the lifetime of the returned resource.
I have checked the test in scastie. I have also tried changing versions, and it already happens with versions 2.5.1 and 2.5.6 of fs2 and cats-effect.
I'll leave this comment here, it may be relevant(I see as == map in both examples).
https://github.com/typelevel/fs2/issues/2785#issuecomment-1007825447