Guaranteeing an actor executes off the main thread

Every actor which is not the main actor executes on a background thread; this is actually a public guarantee and is stated in the documentation: Actor | Apple Developer Documentation. More specifically, if an actor doesn't specify a custom executor, it's given a default executor instance, which simply delegates to that background thread pool.

I think you're assuming that an actor becomes "bound" to whatever place it has been created in, but this is not true; an actor is always its own isolation domain regardless of whether its initializer got called by something running on the main actor or not, and because it already is concurrency-safe, it can execute concurrently with its creator — through using the global threadpool.

The good news is that you don't have to do anything :slight_smile: Looks like you want precisely the default behaviour.


Also, priority is a property of a task, not an actor. That is, if you call the same actor method twice from tasks with different priorities, like so:

func foo() async {
    let myActor = MyActor()
    
    Task(priority: .high) {
        await myActor.synchronousFunction(1)
    }
    
    Task(priority: .low) {
        await myActor.synchronousFunction(2)
    }
}

it only affects the scheduling order of the calls, but never "infects" the actor for the rest of its lifetime.

4 Likes