Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

stop Spring Scheduled execution if it hangs after some fixed time

I have used Spring Framework's Scheduled to schedule my job to run at every 5 mins using cron. But sometime my job waits infinitely for an external resource and I can't put timeout there. I can't use fixedDelay as previous process sometime goes in wait infinitely mode and I have to refresh data at every 5 mins.

So I was looking any option in Spring Framework's Scheduled to stop that process/thread after a fixed-time either it run successfully or not.

I have found below setting which initialized ThreadPoolExecutor with 120 seconds for keepAliveTime which I put in @Configuration class. Can anybody tell me will this work as I expected.

@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
    int coreThreads = 8;
    int maxThreads = 20;
    final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            coreThreads, maxThreads, 120L, 
            TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()
    );
    threadPoolExecutor.allowCoreThreadTimeOut(true);

    return threadPoolExecutor;
}
like image 442
Shams Avatar asked Oct 07 '16 12:10

Shams


People also ask

How do I stop a scheduled spring job?

Another way to stop the scheduler would be manually canceling its Future. In the cases with multiple scheduler tasks, then we can maintain the Future map inside of the custom scheduler pool but cancel the corresponding scheduled Future based on scheduler class.

What is fixed delay in spring scheduler?

Schedule a Task at Fixed Delay In this case, the duration between the end of the last execution and the start of the next execution is fixed. The task always waits until the previous one is finished. This option should be used when it's mandatory that the previous execution is completed before running again.

How do you stop a scheduled job in Java?

The cancel() method is used to cancel the timer task. The cancel() methods returns true when the task is scheduled for one-time execution and has not executed until now and returns false when the task was scheduled for one-time execution and has been executed already.

Is it possible to call a spring scheduled method manually?

There is no limitation to call a scheduled method manually. you can do that with no additional configuration.


1 Answers

I'm not sure this will work as expected. Indeed the keepAlive is for IDLE thread and I don't know if your thread waiting for resources is in IDLE. Furthermore it's only when the number of threads is greater than the core so you can't really know when it happen unless you monitor the threadpool.

keepAliveTime - when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.

What you can do is the following:

public class MyTask {

    private final long timeout;

    public MyTask(long timeout) {
        this.timeout = timeout;
    }

    @Scheduled(cron = "")
    public void cronTask() {
        Future<Object> result = doSomething();
        result.get(timeout, TimeUnit.MILLISECONDS);
    }

    @Async
    Future<Object> doSomething() {
        //what i should do
        //get ressources etc...
    }
}

Don't forget to add @EnableAsync

It's also possible to do the same without @Async by implementing a Callable.

Edit: Keep in mind that it will wait until timeout but the thread running the task won't be interrupted. You will need to call Future.cancel when TimeoutException occurs. And in the task check for isInterrupted() to stop the processing. If you are calling an api be sure that isInterrupted() is checked.

like image 97
JEY Avatar answered Sep 17 '22 13:09

JEY