Cancelling Running Gateway Scripts from Perspective Session

I am curious if there is a native tool that would allow a user to cancel individual scripts from the Perspective Session scope.

In particular, I have built a tool that allows the user to dispatch and monitor several long-running concurrent scripts on asynchronous threads. If possible, I would also like to let them cancel these scripts mid-run from the UI rather than navigating to the relevant section in the Gateway webpage. Is there a scripting function or some other method to achieve this?

My current method is to terminate the session (which automatically cancels the backend scripts tied to it/initiated by it), but this cancels all running scripts at once rather than targeting specific ones.

Versions: 8.1.xx, 8.3.xx

Thanks!

You probably should wean yourself off of asynchronous threads. Killing them is not well-supported by the JVM, and can break it. I recommend using thread pools executing small tasks, or timer events advancing state machines. Break your existing processes down into small tasks and queue them for execution.

If you absolutely cannot avoid async threads, use java's .interrupt() feature instead of termination, and write your async functions to check for interruption regularly. (Unless doing a bunch of I/O, which will throw exceptions when interrupted.)

These tasks are heavily IO-bound (repeated database queries -> data transformation -> file I/O, etc.).

I understand the benefits of a state machine/thread pool approach (predictable thread count regardless of user behavior, dynamic resource allocation, lower overhead, etc.), but I'm not sure how it would work in my application. I am building this tool specifically to be portable between projects/Gateways with as few moving assets as possible, and asynchronous thread implementation keeps all of the processing logic contained in a single project script rather than spread across Gateway configurations, state-monitoring tags or database tables, etc. The main issue is that I have no information regarding the availability of such resources or configurations in the myriad environments where this tool must eventually work.

As I understand it, system.util.invokeAsynchronous is designed to dispatch lightweight virtual JVM threads to handle long-running tasks for exactly this type of use case since it allows Java to handle concurrency under the hood without the programmer needing to manage queues or monitor/backup state. The tradeoff, of course, is that tasks cannot be resumed or retried after failure; I've accepted this since the tasks in question must always be monitored & manually verified by an end user, never left to run and assumed to have succeeded.

All-in-all, I strongly agree with your advice from an architectural perspective but am just lacking in the scope of understanding needed to apply it well in this particular case. Perhaps I am missing some key point that would immediately click everything into place?

Thanks!

Start here:

Write your scripts to check Thread.interrupted() regularly and bail out. Don't kill threads, interrupt them.

Your LLM of choice is lying to you.
Virtual threads weren't even an option until Java 21, and 8.3 runs on Java 17. Even in the 2027 branch, invokeAsynchronous will continue to create and return a heavyweight "real" thread for backwards compatibility.

Are you sure about that?

Good to know about the thread allocations. That explains a lot of memory usage concerns I have had. I may have opened the wrong version of Oracle's documentation when studying the thread interactions (I don't have long-term experience with Java and never looked across older versions to see when virtual threads first became available), which is funny because I tend not to rely on LLMs when studying new-to-me APIs for that exact reason.

As far as cancelling running scripts when a session terminates, I only meant that with regard to my particular backend implementation which routinely monitors for an active session connection with a specified ID, not from an Ignition architecture perspective.