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