Manually Spawning Isolates for Larger Computations in Dart's Flutter Framework

in #utopian-io6 years ago

flutter-logo.jpg

Repository

https://github.com/flutter/flutter

What Will I Learn?

  • You will learn how to manually spawn an Isolate in Flutter
  • You will learn about Ports and Messages for Isolates
  • You will learn about SendPorts and RecievePorts
  • You will learn about the Flutter Task Runners
  • You will learn how the Flutter Platform is structured
  • You will learn how to use await for to deconstruct Streams into Futures

Requirements

System Requirements:
OS Support for Flutter:
  • Windows 7 SP1 or later (64-bit)
  • macOS (64-bit)
  • Linux (64-bit)

Required Knowledge

  • A fair understanding of concurrency and paralellism
  • A fair understanding of Mobile development and Imperative or Object Oriented Programming
  • A simple understanding of asynchronous programming

Resources for Flutter and this Project:

Sources:

Flutter Logo (Google): https://flutter.io/
Flutter Platform Image (Google): https://flutter.io/technical-overview/

Difficulty

  • Intermediate

Description

Outline and Overview

In this Flutter Video tutorial, we take a look at how we can Spawn and Use Isolates in a manual way for more advanced computations. We build out an application that pulls in 500 JSON objects from an API endpoint. We then parse and decode that JSON using our isolate. We then send the data back through a SendPort to the main root Isolate so that it can be displayed on the screen. In our isolate, we also use the await for loop to turn our Port Stream into a set of future values.

Outline for this Tutorial
Item 1: Isolates in the Flutter Platform

The Flutter platform naturally uses four different task runners which are delegated to four threads. The task runners are each responsible for various different types of actions. By distributing their responsibility over multiple threads, flutter is able to make sure that performance is consistent even in situations that use sub-optimal code. As a consequence of having the platform split in this manner, we can also manually delegate expensive processes and computations to Dart Isolates.

platform.jpg

Featured here is a layout of the general Flutter platform. In the top layer, we have most of the Dart code which is mainly what gives the widget's their shapes and paints. On the bottom side, we have a base of c++ which is able to run independent of the Dart code. This includes the Dart Virtual Machine which spawns these Isolates. Non-root isolates in flutter can not schedule frame rendering events and do not have bindings which can interact with the framework in a meaningful way.

Item 2: Communicating between Isolates

Dart's Isolates are very similar to Erlang/Elixir actors. Because they are isolated from one another, they need a way to communicate. The flutter application logic runs on a main root Isolate which is separate from the spawned isolate. We are able to use augmented stream objects called Ports to communicate between Isolates.

load-isolate.jpg

Here is an image of the Load Isolate function that spawns the external Isolate for our application. You can see that the first line defines a ReceivePort. Each port wraps a Dart Stream and has a unidirectional data flow. This means that the ReceivePort is only able to receive data and the SendPort is only able to send data. Due to this fact, when we spawn a SendPort or a ReceivePort, the corresponding Port is also spawned. This means that every ReceivePort also spawns a SendPort and vice versa. In our application, we spawn a ReceivePortfor both the isolate and the main root isolate so that we can send and receive data on both sides. We are even able to send the corresponding SendPort through the SendPort to give the opposing isolate access to the ports.

Item 3: Deconstructing Streams Into Futures

Since the data that is being pushed from isolate to isolate is in stream format, we are able to make use of various abstractions to manipulate this data. One of the powerful ways to manipulate streams is to convert them into Futures via the await for loop. The await for loop lets us iterate through the data of a stream in an asynchronous way that is similar to a normal for loop.

isolate-entry.jpg

In the image above, we you can see the function that we use as an entry point for the external isolate that we spawn. In this function, we take the information that is being passed into the ReceivePort and iterate through it by using the await for loop. We are able to snapshot the data in this way which lets us directly deal with it like we could with any other future. In this case, we just deconstruct it from the list that we are passing through so that we can then preform the JSON computation and send that data back to our Main Isolate.

The source code for this project can be found here

Information about Flutter's Task Runners can be found here

Flutter's Technical Overview can be found here

Video Tutorial

Related Videos

Projects and Series

Stand Alone Projects:
Building a Calculator
Movie Searcher Application

Minesweeper Game

Weather Application

Curriculum

Proof of Work Done

https://github.com/tensor-programming

Sort:  

Hey @tensor

We're already looking forward to your next contribution!

Contributing on Utopian

Learn how to contribute on our website or by watching this tutorial on Youtube.

Utopian Witness!

Vote for Utopian Witness! We are made of developers, system administrators, entrepreneurs, artists, content creators, thinkers. We embrace every nationality, mindset and belief.

Want to chat? Join us on Discord https://discord.gg/h52nFrV

Thank you for your contribution @tensor. Great work.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

As always, Thank you for moderating my contribution.

Coin Marketplace

STEEM 0.30
TRX 0.12
JST 0.033
BTC 62025.59
ETH 3074.98
USDT 1.00
SBD 3.84