Dariell Bowo
Dariell Bowo

Reputation: 31

Spring @Scheduled with fixedDelay=0

I have a method that I'd like to invoke over and over from the start of my application, but I do not want to have a delay in between the end time of the method execution and the start of the new one. Basically doing @Scheduled(fixedDelay=0) will technically do the job, but spring does not allow 0 millisecond for the delay.

Upvotes: 1

Views: 2595

Answers (2)

nonprofitgibi
nonprofitgibi

Reputation: 25

I would avoid using @PostConstruct in this case because if you're starting up an infinite loop on a separate thread in @PostConstruct then you're starting your action before the application is ready. This is an opinionated question but my suggestion is to use @Scheduled(initialDelay=100L) and in that function call your use an executor or a dedicated thread.

As an example:

@Scheduled(initalDelay = 100L)
void startTask() {
    executor.execute(() -> {
        while(true) {
            doSomething();
        }
    });
}

This will be called once and only once 100ms after your application is initialized. Either way you do this the basic and structure is the same and it really just depends on what sort of guarantees you need and opinions you an others have.

@PostConstruct is intended to be used to perform additional initialization tasks for a bean after injection has occurred, but before the bean is made ready. Typically this would be used for a bean that requires hydrating a resource like a cache that is needed before the application can receive requests, but for one reason or another this cache isn't going to be able to be hydrated in the construction. @PostConstruct is not directly related to application state/application lifecycle, it is simply called during bean initialization after all inject-able attributes have been injected (think @Value and @Autowired), after the constructor is called, on the main thread, and before the bean can be injected and used elsewhere.

@Scheduled is intended to be used to run a task on a schedule. The function annotated with @Scheduled is called from the scheduler thread, potentially from a scheduler thread pool depending on how it's used. It will not be called until the application is fully initialized. It can be used to accomplish run once by providing only an initalDelay its a little strange to look at but it works and certainly isn't wrong.

Lastly @EventListener(ApplicationStartedEvent.class) could be used in place of the run once @Scheduled annotation. The upside is it's very obvious what's being done. This function is called once the application has started. The down side is that you have no control over if you want to delay that for a few milliseconds just to be 100% sure that there isn't anything finishing up and you don't end up starting 4 milliseconds before something is made available causing strange behavior for like 1 cycle that is nearly impossible to debug.

Upvotes: 0

Sébastien Helbert
Sébastien Helbert

Reputation: 2210

If zero is not permitted, what about @Scheduled(fixedDelay=1) ? 1 millisecond

Upvotes: -2

Related Questions