I like how C# handles this. You're not forced to support cancellation, but it's strongly encouraged. The APIs all take a CancellationToken, which is driven by a CancellationTokenSource from the ultimate caller. This can then either be manually checked, or when you call a library API it will notice and throw an OperationCancelledException.
Edit: note that there is a "wrong" way to do this as well. The Java thread library provides a stop() function. But since that's exogenous, it doesn't necessarily get cleaned up properly. We had to have an effort to purge it from our codebase after discovering that stopping a thread while GRPC was in progress broke all future GRPC calls from all threads, presumably due to some shared data structure being left inconsistent. "Cooperative" (as opposed to preemptive) cancel is much cleaner.
AbortSignal is same thing on the Web. It's unfortunate TC39 failed to ever bring a CancelToken to the language to standardize the pattern outside browsers.
I don't like it - you're forced to pass around this token, constantly manage the lifecycle of cancellation sources - and incredibly bug prone thing in async context, and it quickly gets very confusing when you have multiple tokens/sources.
I understand why they did it - a promise essentially is just some code, and a callback that will be triggered by someone at some point in time - you obviously get no quality of service promises on what happens if you cancel a promise, unless you as a dev take care to offer some.
It's also obvious that some operations are not necessarily designed to be cancellable - imagine a 'delete user' request - you cancelled it, now do you still have a user? Maybe, maybe you have some cruft lying around.
But still, other than the obvious wrong solution - C# had a Thread.Abort() similar to the stop() function that you mentioned, that was basically excommunicated from .NET more then a decade ago, I'm still not happy with the right one.
C# has very good support for this.
You can even link cancellation tokens together and have different cancellation "roots".
> "Cooperative" (as opposed to preemptive) cancel is much cleaner.
Which what Thread.interrupt does.
I am surprised that you had to go out of your way to remove Thread.stop from existing Java code. It's been deprecated since 1998, and the javadoc page explains pretty clearly why it's inherently unsafe.
It's hard to miss all the warnings unless you're literally just looking at the method name and nothing else.