Skip to content

Instantly share code, notes, and snippets.

@monadplus
Last active May 22, 2019 07:33
Show Gist options
  • Save monadplus/525d9ed2a7c96ee3b5a3f7977eb6134b to your computer and use it in GitHub Desktop.
Save monadplus/525d9ed2a7c96ee3b5a3f7977eb6134b to your computer and use it in GitHub Desktop.
Bracket and resource.

Daniel Spiewak on gitter

Think about the closing action of a bracket. I'll use IO and Resource here as the archetypical examples, but Stream is also a very good exemplar, and obviously all of the cats-effect implementors have IO-like semantics in this regard.

So the closing action of a bracket with IO will be sequenced after the result is produced (or an error, or cancelation). Thus, imagine a chain like fa1 *> fa2 *> fa3. If fa1 is created by bracket, then the finalizer will be sequenced before fa2. Thus, associating to the left over bind.

This is different with Resource, and it represents the critical distinction of that type. If you have a chain ra1 *> ra2 *> ra3, then ra1's finalizer will be sequenced after ra3, and perhaps after other things. The region scope is very different, and the bracket thus associates to the right over bind.

def bracketId(id: String): IO[String] =
  Bracket[IO, Throwable].bracket(putStrLn(s"Acquire $id").as(id))(_.pure[IO])(_ => putStrLn(s"Release: $id"))

bracketId("1") *> bracketId("2") *> bracketId("3")
// Acquire 1
// Release: 1
// Acquire 2
// Release: 2
// Acquire 3
// Release: 3

putStrLn("Acquire 1").bracket(_ => 
    putStrLn("Acquire 2").bracket(_.pure[IO])(_ => putStrLn("Release 2)"))
)(_ => putStrLn("Release 1")
// acquire 1
// acquire 2
// release 2
// release 1

Resource on fs2:

val s1 = Stream.emit(1)
val s2 = Stream.awakeEvery[IO](100.millis).evalMap(c => putStrLn(s"Elapsed: $c"))
// Without resource
(s1.concurrently(s2).compile.lastOrError >> IO.sleep(10.seconds)).run // Prints nothing

// With resource: prints during the lifetime of the resource.
s1.concurrently(s2).compile.resource.lastOrError.use(_ => IO.sleep(3.seconds)).run
// Elapsed: 113548279 nanoseconds
// Elapsed: 217579663 nanoseconds
// ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment