`sending` cancellation handler in `withTaskCancellationHandler`

In my use case I need to handle cancellation with withTaskCancellationHandler that mutates a non-Sendable actor isolated value. The current API accepts the actor isolation input but only accepts Sendable cancellation handler. Is there any way to achieve this?

unsafeBitCast (I presume withTaskCancellationHandler can't actually call its handler more than once but maybe somebody can confirm that)

Disconnected<(() -> Void)?>. You can't consume the Disconnected, but you should be able to take the closure out of the Optional and call it.

Mutex<(() -> Void)?> as a slightly-inefficient Disconnected.

1 Like

Cancellation handlers can and will be called from arbitrary contexts depending on where the task is cancelled from. The handler can definitely be sending instead of @Sendable since they are guaranteed to be called once. However, accessing actor isolated state isn't easily possible inside them since that requires an async context. Two ways to make this work:

  1. Protect the state with a Mutex instead of an actor which will allow you to access the state through the Mutex.
  2. Spawn an unstructured task that dispatches the access to the actor

I would normally recommend against the second approach since I recommend reducing the usage of unstructured tasks but it might be the easier approach that doesn't require a larger refactoring.

4 Likes

The linked doc mentions that cancellation closure is isolated to the passed actor, is the doc incorrect here? I agree the signature API signature doesn't match what the doc mentions, mainly cancellation handler should be sending isolated(any).

I had a similar question before. Here might be some more clues:

1 Like

Thanks for linking this thread @vanvoorden, the doc is wrong here (no surprise there for an Apple doc :sweat_smile: ).

Heh, a lot of the documentation wording in that page explains exactly the right semantics; I see there's one incorrect sentence, I've fixed it now.

Please call out mistakes, open issues, or even PRs to fix these things. There's a lot of folks editing things and sometimes things slip through -- thanks in advance.

7 Likes