Open joggeli34 opened 2 years ago
/cc @mkouba
I must admit that I find the idea interesting. OTOH in most cases the goal of a scheduler method is to execute some logic at a specific time or at a specific interval ;-). Could you be a little more specific about the expected behavior? For example, what exactly should happen if you define @Scheduled(every = "10s", jitter = "1000")
? Should it be executed somewhere between interval - 1000ms
and interval + 1000ms
?
CC @machi1990
For @Scheduled(every = "10s", jitter = "1000")
there could be multiple solutions:
interval +- jitter
interval +- jitter
I think, 2. would be the simplest to describe. But actually, I don't mind exactly which one is implemented, as the interval time is not that important when someone decides to use a jitter.
- At create-time, an interval is fixed with interval +- jitter
Hm, this one would be probably the easiest to implement correctly, OTOH the option 2. would be more understandable... (and option 3 is functionally equivalent to option 2)
@Scheduled(every = "10s", jitter = "1000")
Alternatively, we could support the jitter directly in the @Scheduled#every()
, e.g. via the plus–minus sign: @Scheduled(every = "10s ±1")
.
Alternatively, we could support the jitter directly in the
@Scheduled#every()
, e.g. via the plus–minus sign:@Scheduled(every = "10s ±1")
.
Having a jitter argument makes more sense. It is self explanatory.
- At create-time, an interval is fixed with interval +- jitter
This means the task will be fixed afterwards during runtime, isn't the whole point of having a jitter to introduce a bit of randomness?
Note that this could be difficult (if at all possible) to implement in quarkus-quartz
.
I encountered this feature request today because we have multiple pods processing a queue of work units, and we want to minimize the chances of them trying to start the same unit of work.
Such a jitter feature is thankfully easily emulated with e.g. this code at the begin of the scheduled method:
private static final Random random = new Random();
// ...
try {
TimeUnit.MILLISECONDS.sleep(random.nextLong(jitter.toMillis()));
} catch (InterruptedException e) {
return;
}
I encountered this feature request today because we have multiple pods processing a queue of work units, and we want to minimize the chances of them trying to start the same unit of work. Such a jitter feature is thankfully easily emulated with e.g. this code at the begin of the scheduled method:
private static final Random random = new Random(); // ... try { TimeUnit.MILLISECONDS.sleep(random.nextLong(jitter.toMillis())); } catch (InterruptedException e) { return; }
Keep in mind that this blocks the executor thread which is not always desirable...
I encountered this feature request today because we have multiple pods processing a queue of work units, and we want to minimize the chances of them trying to start the same unit of work.
Maybe a better solution would be to use config properties to slightly adjust the execution time for each pod. For example, something like @Scheduled(cron = "${my.cron.expr:0 15 10 * * ?}")
where the my.cron.expr
is the config property and 0 15 10 * * ?
is the default value - used for pod1. And then for example set ENV variables to adjust the cron expression like MY_CRON_EXPR="0 20 10 * * ?"
for pod2 and MY_CRON_EXPR="0 25 10 * * ?"
for pod3.
Description
It would be nice if the
@Scheduled
annotation also support setting a jitter.We have multiple instances running which are doing periodical tasks / checks. Adding a jitter would better distribute the load of the task randomly.
Implementation ideas
It could be added to the
@Scheduled
annotation similar as it is done in the@Retry
annotation.