1

I'm using a library that has a long-running RPC longRunningCall. Right now I'm submitting Java futures to a thread pool like:

val myFuture = myPool.submit(() => { someLibrary.longRunningCall() })

Unfortunately longRunningCall can hang indefinitely. I first tried waiting for the Future like:

Await.result(myFuture, Duration(30, TimeUnit.Seconds))

This works okay, but the future keeps running in the background, eating up threads in my thread pool.

I then tried catching the TimeoutException and calling myFuture.cancel(true), but it seems like longRunningCall doesn't respect the interruption and keeps running. This means my thread pool eventually just fills up with zombie threads.

How can I run this task in a background thread and actually, forcibly, cancel it using Scala or Java?


I'm aware of many other threads on the topic, but there is an assumption in the answers I see that I have control over the long-running task, e.g.

Future task of ExecutorService not truly cancelling

How to cancel Future in Scala?

How to cancel Java 8 completable future?

As such I do not see a question that is truly a duplicate.

Is this just not possible?

Eric M.
  • 642
  • 5
  • 16
  • 3
    *"Is this just not possible?"* - Correct. – Stephen C Mar 26 '22 at 06:43
  • *"... there is an assumption in the answers I see that I have control over the long-running task"* - If you can't forcibly stop a task that you do have control over, how could you *possibly* stop one that you don't have control over? (Logically, the latter would imply the former .... wouldn't it.) – Stephen C Mar 26 '22 at 06:45
  • 1
    @StephenC I mean, I could launch a child process and then kill that process. I could run the job on an EC2 instance and kill the instance. It can be done -- but is it true that at the level of threads, you just can't cancel a runaway thread? You have to kill the JVM? That's what I want to confirm. – Eric M. Mar 26 '22 at 06:57
  • Yes. As I said. "Correct". – Stephen C Mar 26 '22 at 07:32
  • 1
    If you know the underlying thread the task is running on, you can conceivably call `interrupt` on the thread. That is not preemptive: it sets a flag on the thread saying "you've been interrupted". There are a number of fairly common operations which will check that flag and throw an exception (which generally isn't caught), but there's no guarantee that what's running in that thread will ever see that it's been interrupted. – Levi Ramsey Mar 26 '22 at 13:55
  • If you can, I would suggest looking into **cats-effect** or **ZIO** both support cancellation. – Luis Miguel Mejía Suárez Mar 26 '22 at 15:47
  • Potential duplicate https://stackoverflow.com/questions/71451466/how-do-i-kill-a-java-future/71530845#71530845 – michid Mar 28 '22 at 20:24

0 Answers0