🎉 Black Friday Sale! Save 30% when you subscribe today.

Async Composable Architecture: Tasks

Episode #196 • Jul 11, 2022 • Subscriber-Only

This week we start fixing the problems we outlined last week. We build the tools necessary to start using concurrency tasks directly in reducers, and along the way we open Pandora’s box of existential types to solve some mind-bending type issues.

Previous episode
Async Composable Architecture: Tasks
Next episode
Locked

Unlock This Episode

Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.

Sign in with GitHub

Introduction

So, this is a pretty big missing part of the ergonomics story for the Composable Architecture. We need to figure out a way to use Effect.task in our reducers because there are a ton of benefits:

  • It makes for simpler dependency clients that can just use async instead of returning Effect values, which means that our dependencies don’t even need to depend on the Composable Architecture.

  • It makes for simpler live and mock instances of dependencies

  • It makes for simpler construction of effects in reducers, and we can chain multiple asynchronous tasks together by just awaiting one after another.

  • And finally it means we can even sometimes remove schedulers from our environment, especially if we don’t need to schedule time-based work.

But most importantly, we want to allow usage of Effect.task in our reducers in a way that does not affect tests. Testing is by far the most important feature of the Composable Architecture, and we try our hardest to never add a feature to the library that hurts testability. We should strive to be able to write fully deterministic tests that run immediately.

And Effect.task is really just the tip of the iceberg. There are a lot more ways we’d like to more deeply integrate the library with Swift’s concurrency tools, but let’s start with the problem of Effect.task not being usable in reducers.

The main problem with using async/await directly in the reducer is that all new asynchronous contexts are spun up when effects execute in tests, and we are forced to wait for small amounts of times for those tasks to finish and feed their data back into the system.

Let’s see how we can fix this.

Testing async-received actions


References

  • Collection: Concurrency
    Brandon Williams & Stephen Celis
    Note

    Swift has many tools for concurrency, including threads, operation queues, dispatch queues, Combine and now first class tools built directly into the language. We start from the beginning to understand what the past tools excelled at and where they faultered in order to see why the new tools are so incredible.

Downloads

Get started with our free plan

Our free plan includes 1 subscriber-only episode of your choice, access to 64 free episodes with transcripts and code samples, and weekly updates from our newsletter.

View plans and pricing