Non-suspending alternative to await?

Here's why a Task { ... } wrapper isn't really a solution to the OP problem (if I understand the OP problem; if not, this is an issue I have been mulling on a while):

// nonisolated; 
// eg: bridging from non-Swift code;
// eg: members on an actor bridging some non-async protocol.
nonisolated func startAllThings() {
    Task { await thing.start() }
}
nonisolated func stopAllThings() {
    Task { await thing.stop() }
}

startAllThings()
stopAllThings()
// "works on my computer", but good luck!

A fire-and-forget operation would guarantee that the receiver got a chance to -start- the job without requiring the caller to block for the whole job to finish.

I think I want to write it like this:

nonisolated func startAllThings() { // still not async
    fire_forget_await thing.start()
}

.. where it's ok to block/suspend briefly (?) up until the point that 'thing' is guaranteed to run this "job" next (or even up to the point it would itself suspend?).

The external interactions now sequence correctly -- and are usable from non-async contexts. Of course, "Thing" still has to handle its own reentrancy issues, but this at least is a building block to making that easier.

I know this is not fully baked. This kind of bridge code is really hard to write correctly and I don't like any of the ways I've solved this so far.

1 Like