Fix calculation of next delay for delayed shard allocation

Currently the next delay is calculated based on System.currentTimeMillis() but the actual shards to delay based on the last time the GatewayAllocator tried to assign/delay the shard.

This introduces an inconsistency for the case where shards should have been delay-allocated between the GatewayAllocator-based timestamp and System.currentTimeMillis().

Closes #14765
This commit is contained in:
Yannick Welsch 2015-11-14 23:38:48 +01:00
parent c09103c35b
commit 2206030fe6
1 changed files with 11 additions and 5 deletions

View File

@ -118,11 +118,17 @@ public class RoutingService extends AbstractLifecycleComponent<RoutingService> i
if (nextDelaySetting > 0 && nextDelaySetting < registeredNextDelaySetting) {
FutureUtils.cancel(registeredNextDelayFuture);
registeredNextDelaySetting = nextDelaySetting;
// We use System.currentTimeMillis here because we want the
// next delay from the "now" perspective, rather than the
// delay from the last time the GatewayAllocator tried to
// assign/delay the shard
TimeValue nextDelay = TimeValue.timeValueMillis(UnassignedInfo.findNextDelayedAllocationIn(System.currentTimeMillis(), settings, event.state()));
// We calculate nextDelay based on System.currentTimeMillis() here because we want the next delay from the "now" perspective
// rather than the delay from the last time the GatewayAllocator tried to assign/delay the shard.
// The actual calculation is based on the latter though, to account for shards that should have been allocated
// between unassignedShardsAllocatedTimestamp and System.currentTimeMillis()
long nextDelayBasedOnUnassignedShardsAllocatedTimestamp = UnassignedInfo.findNextDelayedAllocationIn(unassignedShardsAllocatedTimestamp, settings, event.state());
// adjust from unassignedShardsAllocatedTimestamp to now
long nextDelayMillis = nextDelayBasedOnUnassignedShardsAllocatedTimestamp - (System.currentTimeMillis() - unassignedShardsAllocatedTimestamp);
if (nextDelayMillis < 0) {
nextDelayMillis = 0;
}
TimeValue nextDelay = TimeValue.timeValueMillis(nextDelayMillis);
int unassignedDelayedShards = UnassignedInfo.getNumberOfDelayedUnassigned(unassignedShardsAllocatedTimestamp, settings, event.state());
if (unassignedDelayedShards > 0) {
logger.info("delaying allocation for [{}] unassigned shards, next check in [{}]",