Dart — Isolates

Guilherme V.
3 min readJul 5, 2020

--

I recently decided to try to understand a little better how Dart supports asynchronous programming — through Isolates, Zones, Computation, Streams, and Futures — despite being a Single Thread Language. The first step is to learn the foundation better, so it seems Isolates would be a good start. You probably will not be using Isolates often, but this class is the basic block, responsible for supporting everything else.

So, what is an isolate?

You can imagine an Isolate like a box (or context) containing Memory, and a Single Thread running, and Event Loop continuously. When you start your application, Dart VM automatically creates an instance of an Isolate and runs your “main” code on it.

To access the current Isolate being executed, you can Isolate.current. This object offers you some control methods and properties:

By default, the “main” Isolate is also called “main”, and, once main code execution is done, it finishes.

Besides Memory, a single thread, and the event loop, each Isolate also has a ControlPort, which is used to send messages of control and identification.

Every ControlPort is also linked to its SendPort. In theory, we can send messages to this SendPort. They would be received by the ControlPort, and processed by an internal listener. But I wasn’t able to find out a way to register a listener to it.

Overview of an Isolate

I want to be able to create a second Isolate and make them send messages to each other. To be able to register listeners and process messages, we can create a new port called mainControlPort. Once we have created it, we can send messages to it from other Isolates, and the program keeps running, waiting for messages, until it’s manually killed.

The program keeps running after we added a ReceivePort

Now we need to create a second instance of an Isolate. There are different ways to do it; we can create a new isolate using the constructor method Isolate(...)` or use the static method Isolate.spaw. If you have a background on Akka or Elixir, you will notice the resemblance with withActors. For example, suppose we want to create a second Isolate that sends the current timestamp each second:

terminal output

A full example: 2 Isolates with messages coming from both sides

Now a full example, let’s create two isolates and make them communicate with each other. The MainIsolate will send the TimerIsolate a start message, then TimerIsolate will start sending MainIsolates a timestamp after each second.

full example overview

To be able to send messages on both directions, we need to give the TimerIsolate its ControlPort as well, while also informing MainIsolate about it. You can check the full example below; I believe it’s self-explanatory enough:

Terminal output

--

--

Guilherme V.

Mobile software engineer. Trying to create good code. Not always succeeding.