Errata for Modern Concurrency in Swift 2nd Edition

Creating this topic to catch any typos and bugs in the 2nd Edition of Modern Concurrency in Swift, published 15th February 2023.

1 Like


congratulations on the 2nd edition! I reread some parts now. Here’s just some quick comments on the 2nd edition:

Page 11:

• “A Mac running macOS Ventura (13.0) or later. Monterey should work, but this book was written and tested on macOS Monterey, so your mileage may vary”. I think this should be written and tested on macOS Ventura.

Page 59:

• “Task(priority:operation): Schedules operation for asynchronous execution with the given priority. It inherits defaults from the current synchronous context.” Isn’t it inheriting from the calling context, which can be sync or async in practice?

Page 74:

Task.detached(priority: .medium) {
await self
      .updateDownload(name: name, progress: progress)

Shouldn’t there be a warning that progress isn’t reported in FIFO order here? E.g. a progress bar could jump with this I think. As far as I know the order of progress updates is undefined here. Even though it will be mostly in order in practice, but there’s no guarantee correct?

Page 76:

  • “Task.yield(): Suspends the execution of the current task, giving the system a chance to cancel it automatically to execute some other task with higher priority.” As far as I know Task.yield doesn’t only suspends the current Task and resumes it immediately or later, but there’s no cancellation. I’m confused by “giving the system a chance to cancel it automatically”. IMO this should be something like “suspends the execution of the current task, giving the system a chance to execute some other task with e.g. a higher priority and then eventually resumes executing the yielded Task. The system can decide to resume the Task also immediately without running a different Task”.

Page 106:

It might be good to note that there’s no guarantee that messages will be in order. For the example it doesn’t matter much. But for real world use cases it’s maybe important that after a “went away” message there’s always a “came back” message and not another “went away”. But as there’s suspension points and no isolation the order isn’t defined I think.

Page 150:

I’m not sure how deterministic or flaky this test might be in different setups. The test relies on messages getting all requests triggered by count down. Async let creates child tasks. But there’s not much guarantees from the system in terms of when and in what order they execute. What about a single thread pool for example where the countdown child task finishes before the messages child task? Isn’t the only execution guarantee we get from async let that after we await the value it’s completed? I’d rewrite this test so that when calling model.countdown(to: "Tada!") there’s a guarantee the requests AsyncStream is initialized. Or add a note about it.

Page 196:

Again reporting progress via unstructured Task {} should be an undefined order I think.

Page 213:

“You can be certain that ImageLoader doesn’t introduce any concurrency issues, since it’s an actor.”
Is there anything about Actor reentrancy races? I think it’s important to inform readers that actors aren’t always safe by default. Like The Actor Reentrancy Problem in Swift - Swift Senpai

These comments can be seen as questions as I’m likely to overlook some things.

Thank you!

Found one in Chapter 6:

“Additionally, you had to wait until the test under code was complete before you could verify its output.” I think it should be code under test instead of test under code