简体   繁体   中英

How to force a Java REST application into Idle State?

I have a REST application with about 30 endpoints. In addition to these the user can submit a background task to be processed that takes 20-60 minutes. Sometimes its obvious that a submitted request will never finish from the logs, however, the only thing I can do is redeploy the same version of the code.

I want to have the ability to kill the process similar to how I can with mySQL via

'Show Process List' -> 'Kill <ProcessId>'.

I tried to implement with Thread.currentThread().interrupt(), but that didn't really do anything. I am using CompletionService and multi-threading numerous times throughout the application to expedite the processes.

My goal is that I should be able to call this API to return the application to the state that it is in when no processes are running. I checked this post, but it seems like everyone is warning against it.

How to find and stop all currently running threads?

Can this be done?

Why Thread.currentThread().interrupt() Didn't Work

Thread.currentThread() returns the the Thread object for the current thread you are running in, so if you call this outside of your background task thread, it will not return a reference to your background thread. If you want a reference to your background thread you will have to keep track of it yourself.

thread.interrupt() sets an interrupt flag on your thread. But if your thread never explicitly checks the interrupt flag, it doesn't do anything. You will have to periodically check the interrupt flag within your background task and then take appropriate action.

if (Thread.currentThread().isInterrupted()) {
  finishWork(); // Close any resources used.
  return;
}

For your use case I would actually discourage using interrupt() on your background task, especially if you are using a Threadpool. Specifically if you are using a Threadpool, the same thread could be reused to run multiple background tasks. Because the thread is reused it is possible to accidentally interrupt a background task you never intended to.

How To Stop Background Tasks

This will take a fair amount of work of work to do, but it is doable. Below I describe a very rudimentary implementation that will be sufficient for your use case.

  1. First you will have to create something like a SpringBoot service. Which is a singleton class that gets injected into all of the classes that execute your rest endpoints. The service would be a background task tracker, which keeps a mapping from task ID to a flag indicating whether the task should be terminated.
  2. Next you would have to create a rest endpoint to terminate a background task. The rest endpoint should take the task ID to terminate as a query param or path param.
  3. When the endpoint executes you can call a terminate method on the background task tracker which will flip the flag indicating that the task should be terminated. Note: Your background task may have finished before you actually terminate it so your code should handle this corner case.
  4. When you launch your background task you should give it a reference to your background task tracker.
  5. The very first thing your background task should do is create a unique task ID. You can start with using UUID.randomUUID() .
  6. After creating the task ID give it to your background task tracker.
  7. Print the task ID in the logs for your background task.
  8. The background task can proceed to do its work, but it should periodically check the background task tracker if it has been cancelled. If not continue processing, if yes close any resources used and return.
  9. Before your background task exits, you should remove it from the background task tracker in order to avoid a memory leak.

Important Notes

Before implementing this be sure to read up on how to properly synchronize communication between threads in java. This is a good resource https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM