Is it possible to assign @Scheduled with a period representing "never" (in Spring)?
Asked Answered
F

2

8

I'm investigating using @Scheduled at a fixed rate where in some configurable circumstances the scheduled job should never be run.

The documentation doesn't mention this but the default values for fixedDelay() and fixedDelayString() are -1 and "" respectively. Can these be used to reliably ensure that the scheduled method doesn't fire?

Fridafriday answered 5/10, 2015 at 10:33 Comment(0)
I
7

You can not. When you set the fixedDelay attribute to -1 or attempt use @Scheduled without specifying a valid value for any of its attributes, Spring will complain that no attribute is set:

Exactly one of the 'cron', 'fixedDelay(String)', or 'fixedRate(String)' attributes is required

You can verify this behavior by going through the source code of ScheduledAnnotationBeanPostProcessor#processScheduled.

It contains logic like:

boolean processScheduled = false;

// ...

if (fixedRate >= 0) {
    Assert.isTrue(!processedSchedule, errorMessage);
    processedSchedule = true;
    this.registrar.addFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay));
}

// ...

Assert.isTrue(processedSchedule, errorMessage);

Take a look at this SO post for some options for conditionally disabling @Scheduled.

Islamize answered 5/10, 2015 at 11:11 Comment(7)
Oh, that's a shame - thanks for looking into it. I guess one possible workaround not mentioned in the post you linked might be to set extremely high (i.e. the max long) values for initialDelay and fixedDelay so they are never actually reached. This may work in practice but just seems a bit wrong to have to resort to this and a shame that Spring didn't provide a "never" option.Fridafriday
@SteveChambers Yes, that seems like a bit of a hack. Plus if you were to retrieve the value from configuration and set it using fixedDelayStr, it would be parsed using Integer.parseInt not Long.parseLong, so setting it to max value of long would fail :) ... I will report it later on Spring JIRA.Islamize
Oh dear, it seems fixedDelayStr is out of the question for this method then as the max integer is 2147483647, which (if my Google-assisted calculations are correct) in milliseconds equates to just 3 and a half weeks - bit different to the 292471208 years I think a long would allow!Fridafriday
@SteveChambers Edit: the parsing seems to be already fixed (at least in master, probably in 4.2 too). However the current Spring version I'm using (4.1.7) still has this problem.Islamize
Thanks @Bohuslav. Unfortunately we're using 4.17 too - might have to see if it's possible to migrate...Fridafriday
Looks like without the upgrade another option would be a cron expression. This answer relates to Quartz but would expect something simple like 0 0 0 1 1 ? 2099 should do the job (and am willing to take the hit on the "year 2099 bug"!)Fridafriday
Oh dear, again maybe not - need milliseconds precision, which unfortunately cron doesn't seem to provide.Fridafriday
C
1

As mentioned in spring docs, you can specify "-" to disable the triggering of the task:

CRON_DISABLED: A special cron expression value that indicates a disabled trigger: "-".

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html#CRON_DISABLED

Condescendence answered 24/12, 2021 at 9:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.