Submitting a background task from spring mvc app
Using thread ID is too low level and brittle. If you decided to use @Async
annotation (good choice) you can use Future<T>
to control the task execution. Basically your method should return a Future<T>
instead of void
:
@Asyncpublic Future<Work> work() //...
Now you can cancel()
that Future
or wait for it to complete:
@ResponseBody@RequestMapping("/job/start")public String start() { Future<Work> future = asyncWorker.work(); //store future somewhere return "start";}@ResponseBody@RequestMapping("/job/stop")public String stop() { future.cancel(); return "stop";}
The tricky part is to store the returned future
object somehow so it is available for subsequent requests. Of course you cannot use a field or ThreadLocal
. You can put in session, note however that Future
is not serializable and won't work across clusters.
Since @Async
is typically backed by thread pool, chances are your tasks didn't even started. Cancelling will simply remove it from the pool. If the task is already running, you can the isInterrupted()
thread flag or handle InterruptedException
to discover cancel()
call.