A way to abort or cancel threads

As a Roblox developer, it is currently too hard to cancel the execution of threads.

If Roblox is able to address this issue, it would improve my development experience because it would allow me to implement a real task architecture, without engine errors or constant polling.

If I could target a specific thread and forcefully kill it, I could use an actual task architecture where tasks can be spawned and cancelled on the fly, which is perfect for user actions, or generator code.

Additionally, games like Lua Learning and Void SB could greatly benefit from a feature like this because it would make it possible for them to safely terminate user ran code, and, my script sandboxing tool would greatly benefit for the same reason.

29 Likes

Something like this would fit in perfectly with the new task library.
For example, as task.kill or task.cancel.

Currently, I only really have one problem with the new (very powerful) task library… Technically, I can’t actually implement a real task architecture, because I can’t cancel a task.

In other words, the task library in its current form is less of a full fledged task library and more of a powerful extension of the coroutine library with some extra thread scheduling goodies.

Example:

local thread = coroutine.create(someTaskFunction)
task.spawn(thread)

-- Later
-- We don't want to do any more work, maybe this is a user action and the user stopped it, so, cancel the task
task.cancel(thread)

I would absolutely love the ability to implement full fledged tasks. I could for example refactor a lot of the input code in my game to not look like this:

if not self.Active then
	return
end
-- a yield
if not self.Active then
	return
end
-- etc

Edit:
I did a little research on this, for people that are interested in the extra details:

Task cancellation & how its implemented in other languages

Summary of different methods of task cancellation

Involuntary

There are two ways of involuntarily ending threads/tasks. One is to just forcefully end a task, which, is currently impossible without abusing BaseScripts and .Disabled. This is the sort of cancellation that Roblox should absolutely provide support for.

The other way is throwing an error at yield points. This is possible in luau by overriding every point where a thread can yield (which is what my script sandbox does), but, built in Roblox functions don’t support it which results in unwanted engine errors.

Voluntary

A thread has to poll for whether or not it should be cancelled. Currently, this is the easiest way to do this in luau, but, Roblox functions don’t support this, also resulting in unwanted engine errors depending on implementation.

Implementations of task cancellation in other languages

Python

Coroutines and Tasks — Python 3.11.1 documentation
Python allows for coroutines to be ran and cancelled at any time, and provides an ability to shield code from being cancelled.

This is the sort of architecture that would be perfect in Roblox.

C++11

asynchronous - cancel a c++ 11 async task - Stack Overflow
C++11 doesn’t have any official or built in way to safely cancel threads/tasks, but, the above Stackoverflow answer outlines several ways that the end user can implement cancellation.

This discusses two ways of doing thread cancellation (with varying safety levels) without requiring the thread body to voluntarily check a cancellation condition. The third way is the same way the two below languages implement task cancellation.

C# and Java

Task Cancellation | Microsoft Learn
Java SE 9 & JDK 9
C# and Java both do the reverse, which, is more appropriate for lower level languages, and requires that tasks poll when they want to cancel. Luau doesn’t natively support task cancellation from the user-level which results in undesired engine errors if a thread resumption is queued.

13 Likes