I actually kind of feel the opposite—in particular, this feedback:
is IMO exactly what I think a 'new term of art' should aim to achieve. The semantics here are very subtle and I don't think we're going to be able to pick a name which sufficiently communicates in three or four words how all the different edge cases will behave. It's much better for people who encounter this to scratch their heads a bit before they read the docs than to read a succinct name which implies something incorrect about the behavior.
I still think that shield is fairly evocative for the behavior described here, if one adopts the mindset that it's the scope that is shielded rather than a notional observer who moves along with the program counter. Moreover, task cancellation does not act like an arrow, but more like sunlight: cancellation hits the entire task 'at once', but the notional observer may ride the program counter between shielded regions where they can be shaded and pretend its still night.
In any case, I agree that our docs for this feature should take great pains to explain why this behavior is different from 'ignoring' cancellation, but I don't think it's the job of the name to do much more than think "huh, this has some effect on task cancellation... what does it do again?" And I am perfectly happy if we have minor qualms about how perfect the metaphor is so long as it doesn't easily lead to misinterpretations. Judging alternatives from this thread by that standard:
withTaskCancellationDeferred: I think this suggests something too similar to 'ignored', that cancellations which happen inside the block would not actually have any effect until the end. But IIUC if there were a task cancellation handler outside the shield then it would run immediately upon a call totask.cancelfrom within the shield.withTaskCancellationSuspended: "suspended" as a term of art here is decent, IMO. I don't think this immediately suggests any improper semantics.withTaskCancellationInAbeyance: doesn't suggest anything wrong, but IMO is too obscure—assume this one was half-joking.
ignoringOutsideCancellation: decent qualification of the "ignore" terminology IMO! It misses thewithand theTaskas part of the name, andwithOutsideTaskCancellationIgnoredstarts to get pretty wordy IMO. "Outside" is not immediately clear, so clears the bar of "gets someone to look at the docs".ignoringParentCancellation: the problem with this that I see is that this is really an operation that affects the execution of the current task rather than the parent task—we don't really talk about the current execution environment having the current task as a 'parent'.withoutPropagatingTaskCancellation: I think this too easily suggests only the "child tasks won't get cancelled if parent task gets cancelled without hinting at all that there's something more (i.e.,Task.isCancelledstarts lying.
Agree that this should be the behavior if it isn't already, and that the proposal should make this clear!
While I don't see an example in the proposal that confirms this, I assumed that hasActiveTaskCancellationShield would return true even if the task is not cancelled—that is, in:
Task {
withTaskCancellationShield {
withUnsafeCurrentTask {
print($0!.hasActiveTaskCancellationShield)
}
}
}
we'd always expect it to print true. Granted, given that the stated use case is to demystify "why isn't my Task.isCancelled true?" I don't know that the above behavior is needed. But also, giving an API for this specific scenario is IMO more useful than relying on the impicit knowledge that Task.isCancelled != task.isCancelled always means "you're inside a task cancellation shield". I think it's reasonable to give an UnsafeCurrentTask property for inspecting the value of this task record property directly rather than merely having a roundabout way of spelling it.