[Concurrency] Structured concurrency

Yes add currently is async on purpose. That’s an idea we’re pursuing — a nursery can provide a form of back-pressure by not resuming the add immediately and therefore only keep a limited number of tasks enqueued at any given time.

I agree though that it reads a bit weird, or rather, takes getting used to. We’re not yet sure if a lot of code day to day would interact with those directly, or use provided operations built on top of nurseries / task scopes — in which case them looking a bit more complex would be less of an issue...

To clarify:

withNursery { nursery in 
for w in work {
  await nursery.add { // awaiting on the _submission_ of task
    await w.work() // actually awaiting on the task, 
                  // when it’s going to run
  }
  // ... 
}

So what this code is saying is that “adding can suspend”, e.g. because a nursery could be configured to “never have more than 1,000” outstanding tasks, or similar.

We’ll have to learn and see once we have things up and running though if this is reasonable or not... It’s been a design we wanted to bring up and try out though (though we do not have a working infra yet, so it’s hard to judge the usefulness in the real world other than “it would be very good to be able to provide back-pressure here”).

8 Likes