Chapters

Hide chapters

Modern Concurrency in Swift

Second Edition · iOS 16 · Swift 5.8 · Xcode 14

Section I: Modern Concurrency in Swift

Section 1: 11 chapters
Show chapters Hide chapters

10. Actors in a Distributed System
Written by Marin Todorov

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the previous chapters, you learned how to run concurrent tasks in parallel on multiple CPU cores. Furthermore, you learned how to use actor types to make concurrency safe. In this last chapter of the book, you’ll cover the advanced topic of distributed actors: actors that run locally as well as in other processes — or even on different machines altogether.

actor actor actor Laptop Desktop

There are multiple reasons you’d want to make use of distributed actors, for example:

  • To run code in a child process on the same machine. This way, if a fatal error crashes the child process, your main process will continue working and can even start a new copy of the child.
  • To run a process on a remote machine, like a database server. This way, you don’t need to use REST or GraphQL to send and receive data. You simply call methods directly on objects running on the server.
  • Finally, you can use a cluster of devices to perform many tasks as an ensemble.

The distributed actors model has been around for some time, and libraries offer actors and distributed actors for many languages. Therefore, this chapter includes only a minimal amount of theory that covers the model in general.

Understanding the State of Distributed Actors in Swift

Distributed actors were part of Swift’s larger set of proposals for modern concurrency. When Swift 5.5 introduced async/await initially, it did have partial experimental support for the distributed language feature, but not all implementations were complete. As the new concurrency features of async/await, tasks, groups and actors improved over a number of minor releases, the distributed actors did not, holistically speaking, land.

At the time of this writing, the latest Swift version is 5.8, and distributed actors have been around for more than a year, but the support for real-world usage still feels like a work-in-progress in some ways:

  • The feature is still described as experimental.
  • The documentation is somewhat unclear; it contains typos and still looks like a draft version.
  • Generally, the guidelines are that actor systems are challenging to build, and developers shouldn’t build them. However, there are yet to be any officially released systems by Apple for developers to use.
  • The examples provided officially use a combination of async/await, classes, locks and notifications instead of leveraging modern concurrency in Swift.

Given all of the above, since it covers an experimental Swift feature, this chapter is also experimental. But it’s fun!

In this chapter, you’ll work on a project that includes an almost completed distributed actor system. You’ll make a few changes to each key part: the network service, the actor system itself, the distributed actor, and the app that puts it all together.

In doing this, you’ll understand how the network layer and the system work, which should give you a better understanding of how to use distributed actors if one day you have access to an official actor system or if you decide to build one yourself.

Work through the chapter with the understanding that the project follows the basics of Apple’s examples and is, therefore, just a sample system for learning purposes.

Great work on making your way through this rather lengthy disclaimer! Now, it’s time to get to it…

Evolving Local to Distributed

You’re already familiar with actors; they isolate state by putting an automatic barrier between the type’s synchronized internal state and when accessing the synchronized scope from “outside”. That means calls from other actors are considered outside access and automatically made asynchronous:

urhiwXazlac() AxqacQxwi gvayo ahikaceib iiszogu ezsdgjdopuaj uhzobm NgEnnev kqWun cxNobvab() ibjuyo hstvxxeseet obwomv

ItmikWkge golauboyoq tidff pu nri ihkih la tkipimh rba qbonir rjumo PkEnnil

axaxIysehs() Gahatidu Iwcut gvulu usolofeun niycupm mfegvzugx Ricinite Evsiq upewUgnaqp() Yirqik Niwahi DqWeej Ukzefz Gisurowe

Getting Started With SkyNet

In this chapter, you’ll work more on the project from Chapter 7, “Concurrent Code With TaskGroup”.

Connecting to Devices via Bonjour

At the end of Chapter 7, “Concurrent Code With TaskGroup”, you completed the Sky project. The user can start a scan by tapping Engage systems, and the app will concurrently iterate over sectors in satellite imagery and scan them.

HhamBtirwxucv VVMiactk XemcapiHxasxum MHPeefzp PannariOtnojxisir CBVakqias kimnd ocnujl ip xuhmihl icrihgunok lupq no bemluvw weznz/bocuijux kuxe

Creating a Distributed Actor

Firstly, you’ll explore the distributed keyword. You prefix an actor, property or method with distributed to indicate that these might be invoked remotely.

Tracking Devices on the Local Network

The Bonjour service plays two key roles in network discovery. On one side, it “advertises” the current device on the network; on another, it listens for announcements from other devices. This way, effectively, each device tracks all other devices on the network:

Managing Actors in a Distributed System

An actor system may take on many tasks; using or managing a data transport such as Bluetooth, encode and decode invocations across the wire, manage a list of available remote actors, receive remote requests and many others.

Kapawmej/ruzobuxbok irjeqt Hoqx oj ilgiq u qircike Kiroagi ir ofdut u pazfoxe Akrala ravcar gopu Utwaza vuyapofexm Inhira fupuqr dkho Awrega yadruc tecivafn Yuzy oqpigis juxc bu firoewes Raji bjoyt uy uhuba cuj meseronb

Using a System Instead of a Single Actor

In this section, you’ll leave behind the service and the actor system and move on to updating the app model.

Updating the UI to Showcase Collaborative Work

While it’s pretty impressive to make simulators join SkyNet and work together, presentation is important, too. Right now, collaborating on the search for alien life seems a little…unspectacular.

Retrying Failed Tasks

While it might seem like you’re finished with this chapter, there’s one final task to take care of.

Key Points

  • Systems of distributed actors communicate over a transport layer that can use many different underlying services: local network, Bonjour, REST service, web socket and more.
  • Thanks to location transparency, regardless of whether the actor method calls are relayed to another process or a different machine, you use a simple await call at the point of use.
  • In a system of distributed actors, each needs a unique address to relay requests reliably to the target peer and the responses delivered back to the original actor.
  • Using distributed actors can fail for a myriad of reasons, so asynchronous error handling plays an even more significant role in such apps.
  • Last but not least, a distributed app uses the same APIs as a local app: async/await, task groups and actors. The actor model allows for encapsulating the transport layer and keeping its implementation hidden from the API consumers.

Where to Go From Here?

Completing this book is no small feat!

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now