Skip to main content
Version: 1.0.18

Supervisor

A Supervisor[A] is allowed to supervise the launching and termination of fibers, producing some visible value of type A from the supervision.

Creation

track

The track creates a new supervisor that tracks children in a set. It takes a boolean weak parameter as input, which indicates whether track children in a Weakset or not.

val supervisor = Supervisor.track(true)
// supervisor: zio.package.UIO[Supervisor[zio.Chunk[zio.Fiber.Runtime[Any, Any]]]] = zio.ZIO$EffectTotal@1fab7211

We can periodically, report the status of the fibers of our program with the help of the Supervisor.

fibersIn

The fibersIn creates a new supervisor with an initial sorted set of fibers.

In the following example we are creating a new supervisor from an initial set of fibers:

def fiberListSupervisor = for { 
ref <- Ref.make(SortedSet.from(fibers))
s <- Supervisor.fibersIn(ref)
} yield (s)

Supervising

Whenever we need to supervise a ZIO effect, we can call ZIO#supervised function, supervised takes a supervisor and return another effect. The behavior of children fibers is reported to the provided supervisor:

val supervised = supervisor.flatMap(s => fib(20).supervised(s))

Now we can access all information of children fibers through the supervisor.

Example

In the following example we are going to periodically monitor the number of fibers throughout our application life cycle:

object SupervisorExample extends zio.App {
import zio.duration._

val program = for {
supervisor <- Supervisor.track(true)
fiber <- fib(20).supervised(supervisor).fork
policy = Schedule
.spaced(500.milliseconds)
.whileInputM[Any, Unit](_ => fiber.status.map(x => !x.isDone))
logger <- monitorFibers(supervisor)
.repeat(policy).fork
_ <- logger.join
result <- fiber.join
_ <- putStrLn(s"fibonacci result: $result")
} yield ()

def monitorFibers(supervisor: Supervisor[Chunk[Fiber.Runtime[Any, Any]]]) = for {
length <- supervisor.value.map(_.length)
_ <- putStrLn(s"number of fibers: $length")
} yield ()

def fib(n: Int): ZIO[Clock, Nothing, Int] =
if (n <= 1) {
ZIO.succeed(1)
} else {
for {
_ <- sleep(500.milliseconds)
fiber1 <- fib(n - 2).fork
fiber2 <- fib(n - 1).fork
v2 <- fiber2.join
v1 <- fiber1.join
} yield v1 + v2
}

override def run(args: List[String]) = program.exitCode
}