Correct usage of Task?

I’m new to Swift structured concurrency and Actors.

I think I’ve correctly used Task in an Actor, but it just feels… too simple? Which is an amazing review of Swift Concurrency if I in fact did get it right?! :smiley:


extension POWActor {
    func work() async throws -> POW {
        try await Task<POW, Swift.Error>(priority: .userInitiated) {
            while true {
                guard
                    Date() < config.deadline
                else {
                    throw SHA256TwicePOWWorker.Error.timeout
                }
                
                updateOutputByHashingNonce()
                
                if state.output.leadingZeroBitCount() >= config.difficulty {
                    return POW(
                        state: state,
                        config: config,
                        input: input
                    )
                } else {
                    state.nonce += 1
                }
            }
        }.value
    }
}

This is a simple Proof of Work implementation, you find the Swift Package Arbeta here.

So my questions:
Will this in fact run in the background (the Actor is not marked as @MainActor?
Is the priority userInitiated correct? My idea is that somewhere in some app a user initiated an action, which required PoW?

What is PoW?

POW = Proof of Work (wiki)

Yes.

The actor works on its own, independent concurrency context, and Tasks created within in an actor method inherit the priority and context of the actor.

That said, I'm not sure the await Task { ... }.value is actually doing anything, for that reason. It's running on the actor's context, but you already launch it from the actor's context.

I don't think so. Tasks created within an actor method inherit the priority that method was called with. IMO it is better to allow that information to be propagated automatically rather than assuming a specific priority.

Also, userInitiated denotes a very high priority task. It is generally not advised for long-running operations, as it will get priority over most other tasks running in your application.

User-initiated tasks are second only to user-interactive tasks in their priority on the system. Assign this class to tasks that provide immediate results for something the user is doing, or that would prevent the user from using your app. For example, you might use this quality-of-service class to load the content of an email that you want to display to the user.

Apple Developer Documentation

3 Likes