Reputation: 656
I have a task that i need to perform at the time of application startup in spring (context start). There were cases when that task can fail (data may not be ready) and its causing the application start to fail. My question is :
Upvotes: 1
Views: 1767
Reputation: 656
What @Angelo provided can work too.
I am going with following. Which will be running this task after context refresh/start is done.
@Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomething()
{ // something that should execute on weekdays only }
NOTE: The requirement changed a bit where i have to do this task everyday at-least once hence using @Scheduled
Upvotes: 1
Reputation: 12225
A bit hacky, but might do the trick:
@Component
public class SomeBean {
@PostConstruct
public void doTask() {
int i = 0;
try {
doTheTask();
} catch (final Exception e) {
if (i == 10) {
throw new RuntimeException(e);
}
Thread.sleep(200);
i++;
}
}
}
This will run the task 10 times before giving up, waiting 200ms between each attempt. Note that if the same thread that is being put to sleep here is used to ready the data, it won't help, you would have to put the running of the task in a separate thread.
Another possibility is using Spring
's @Scheduled
:
First, you need to enable scheduling. This is done either by the @EnableScheduling
in your java config, or with some xml:
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="myBean" method="printMessage" fixed-delay="5000" />
</task:scheduled-tasks>
<task:scheduler id="myScheduler"/>
Next, annotate the method with @Scheduled
:
@Scheduled(initialDelay= 600000) //ms, =10 minutes
public void doTask() {
doTheTask();
}
Note that there is still no guarantee for the task actually succeeding. You could combine it fixedDelay
to run it multiple times, but note that any exception thrown out of the method will halt the series of execution. For a more guaranteed run-approach, something like this should work (looks a bit odd with throwing exception on success though..)
//numbers in ms, 10 minutes before the first run, then a new attempt every minute
@Scheduled(initialDelay= 600000, fixedDelay = 60000)
public void doTask() {
try {
doTheTask();
} catch (final Exception e) {
//do nothing, retry in 1 minute
return;
}
trow new AbortScheduledException("Task complete"); //made up exception with descriptive name..
}
Upvotes: 0
Reputation: 6954
You may create a spring component listening for the spring context started event. Something like this:
@Component
public class SpringCtxListener {
@EventListener
public void checkUser(ContextRefreshedEvent cre) throws Exception
{
//This method is called when Spring context has started and here you can execute your task
}
}
Angelo
Upvotes: 3