How to currently offload stateless blocking work? Hidden executor API?

Is it just supposed to be this … ?

In a world without custom executors, it does make sense, IMO, to model complex concurrency problems using existing primitives, like Dispatch, and then bridge the results over to Swift concurrency using continuations.

Having said that, this is a concern:

DispatchQueue.global().async {
    someHeavyStatelessBlockingFunctionTaking10Seconds()
    …
}

Using a Dispatch global concurrent queue like this is not wise. I’m hoping that was just for the benefit of a simple example, and in your real code you do better, but I see this a lot in the wild so I want to call it out.

A Dispatch global concurrent queue can [1] overcommit — that is, start more threads than there are CPU cores — which means that it may tolerant this sort of thing more than the Swift concurrency cooperative thread pool. However, this is far from best practice. Specifically, it’s a common cause of thread explosion, which is about as much fun as it sounds. Our general advice is that you avoid concurrent queues in almost all circumstances. For more background on this, see:

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

[1] Whether it will overcommit is a more complex question.

5 Likes