How To Achieve Concurrency in ZIO?

two businessmen outdoor using technology
Reading Time: 2 minutes
Zio Fibers

This article is about ZIO’s support for asynchronous, parallel and concurrent programming and we will see how we can achieve concurrency using fibers model.

Since ZIO is built on a fibre concept, we will start by studying what fibres are and how they vary from threads. We will learn the basic operations on fibers including forking them, joining them,
and interrupting them.

What are Fibers ?

Compared to threads, fibres are more lightweight. A fibre, similar to a thread, simulates a computation that is currently running, and each instruction on a fibre is carried out in order.

Although maintaining this many threads would have a significant performance impact, creating fibres is far less expensive than maintaining operating system threads, thus we can have hundreds of thousands of fibres in our application at any given moment.

Operations on Fibers

Forking a Fiber

Forking creates a new fiber that executes the effect being forked concurrently with the current fiber.

For example, in the following code approach1 is guaranteed to complete execution before approach2 begins execution because both effects are being performed on the same fiber:

lazy val example1 = for {
_ <- approach1
_ <- approach2
} yield ()

On the other hand, if we fork approach1 then the order of execution is no longer guaranteed:

lazy val example1 = for {
_ <- approach1.
fork
_ <- approach2
} yield ()

Joining Fibers

While fork executes a computation concurrently with the current one, join waits for the result of a computation being performed concurrently and makes it available to the current computation.

An important characteristic of join is that it does not block any underlying operating system threads. When we join a fibers, execution in the current fiber can’t continue until the joined fiber completes execution.

A fibre that has failed will fail if it is joined because joining a fibre communicates the outcome of that fibre back to the current fibre. Instead, we can use await to wait for the fibre while being prepared to handle its outcome, success or failure.

trait Fiber[+E, +A] {
def join: IO[E, A]
}

Joins the fiber, which suspends the joining fiber until the result of the fiber has been determined. Attempting to join a fiber that has erred will result in a catchable error. Joining an interrupted fiber will result in an “inner interruption” of this fiber, unlike interruption triggered by another fiber, “inner interruption” can be caught and recovered.
Returns: IO[E, A]

Reference

For more detailed explanation use: https://zio.dev/
Tech hub: Concurrency in Zio

Written by 

Pallav is working as Software Consultant at Knoldus Inc. He is a technology enthusiast and a keen learner with more than 1.5 years of experience. He works as a Quality Catalyst in the organization. He has a good understanding of programming languages like Java and Scala. He likes to listen to songs and playing table tennis.