Skip to content

Commit

Permalink
Refactor config and fixed comments
Browse files Browse the repository at this point in the history
  • Loading branch information
sajid riaz committed Sep 6, 2024
1 parent 37b1448 commit 7413d73
Show file tree
Hide file tree
Showing 9 changed files with 300 additions and 129 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
* Expose AgentNativeConnectionProvider on Connection and Application Module - Issue #673
* Create DatacenterAwareConfig to add Hosts in CQL Session Through ecc.yml - Issue #671
* Create Initial project Structure for Agent - Issue #695
* Retry Policy for Jmx Connection -Issue #700
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,20 @@

public final class RetryPolicyConfig
{

private static final int DEFAULT_MAX_ATTEMPTS = 5;
private static final long DEFAULT_DELAY = 5000;
private static final long DEFAULT_MAX_DELAY = 30000;
private static final long DEFAULT_INITIAL_DELAY = 86400;
private static final long DEFAULT_FIXED_DELAY = 86400;

@JsonProperty ("maxAttempts")
private Integer myMaxAttempts = DEFAULT_MAX_ATTEMPTS;
@JsonProperty ("delay")
private long myDelay = DEFAULT_DELAY;
@JsonProperty ("maxDelay")
private long myMaxDelay = DEFAULT_MAX_DELAY;
@JsonProperty ("unit")
private String myUnit = "seconds";
@JsonProperty ("initialDelay")
private long myInitialDelay = DEFAULT_INITIAL_DELAY;
@JsonProperty ("fixedDelay")
private long myFixedDelay = DEFAULT_FIXED_DELAY;

public RetryPolicyConfig()
{
}

public RetryPolicyConfig(final Integer maxAttempts,
final Integer delay,
final Integer maxDelay,
final String unit,
final long initialDelay,
final long fixedDelay)
{
this.myMaxAttempts = maxAttempts;
this.myDelay = convertToMillis(delay, unit);
this.myMaxDelay = convertToMillis(maxDelay, unit);
this.myUnit = unit;
this.myInitialDelay = initialDelay;
this.myFixedDelay = fixedDelay;
}
private static final int DEFAULT_MAX_ATTEMPTS = 5;
private static final long DEFAULT_DELAY_IN_MS = 5000;
private static final long DEFAULT_MAX_DELAY_IN_MS = 30000;
private static final long DEFAULT_INITIAL_DELAY_IN_MS = 86400000;
private static final long DEFAULT_FIXED_DELAY_IN_MS = 86400000;
private static final String DEFAULT_TIME_UNIT_IN_SECOND = "seconds";
private RetryPolicyConfig.RetryDelay myRetryDelay = new RetryPolicyConfig.RetryDelay();
private RetryPolicyConfig.RetrySchedule myRetrySchedule = new RetryPolicyConfig.RetrySchedule();
@JsonProperty ("maxAttempts")
private Integer myMaxAttempts = DEFAULT_MAX_ATTEMPTS;

@JsonProperty ("maxAttempts")
public Integer getMaxAttempts()
Expand All @@ -68,90 +44,184 @@ public Integer getMaxAttempts()
@JsonProperty ("maxAttempts")
public void setMaxAttempts(final Integer maxAttempts)
{
this.myMaxAttempts = maxAttempts;
if (maxAttempts != null)
{
this.myMaxAttempts = maxAttempts;
}
}

@JsonProperty ("delay")
public long getDelay()
public void setRetryDelay(final RetryDelay retryDelay)
{
return myDelay;
myRetryDelay = retryDelay;
}

@JsonProperty ("delay")
public void setDelay(final Integer delay)
public RetryDelay getRetryDelay()
{
this.myDelay = convertToMillis(delay, myUnit);
return myRetryDelay;
}

@JsonProperty ("maxDelay")
public long getMaxDelay()
@JsonProperty ("retrySchedule")
public RetrySchedule getRetrySchedule()
{
return myMaxDelay;
return myRetrySchedule;
}

@JsonProperty ("maxDelay")
public void setMaxDelay(final Integer maxDelay)
@JsonProperty ("retrySchedule")
public void setRetrySchedule(final RetrySchedule retrySchedule)
{
this.myMaxDelay = convertToMillis(maxDelay, myUnit);
myRetrySchedule = retrySchedule;
}

@JsonProperty ("unit")
public String getUnit()
private static long convertToMillis(final Long value, final String unit)
{
return myUnit;
return switch (unit.toLowerCase(Locale.US))
{
case "milliseconds" -> value;
case "seconds" -> TimeUnit.SECONDS.toMillis(value);
case "minutes" -> TimeUnit.MINUTES.toMillis(value);
case "hours" -> TimeUnit.HOURS.toMillis(value);
case "days" -> TimeUnit.DAYS.toMillis(value);
default -> throw new IllegalArgumentException("Unsupported time unit: " + unit);
};
}

@JsonProperty ("unit")
public void setUnit(final String unit)
/**
* Configuration for retry delay parameter.
*/
public static final class RetryDelay
{
this.myUnit = unit;
// Recalculate delays with the new unit
this.myDelay = convertToMillis((int) TimeUnit.MILLISECONDS.toSeconds(this.myDelay), unit);
this.myMaxDelay = convertToMillis((int) TimeUnit.MILLISECONDS.toSeconds(this.myMaxDelay), unit);
}
public RetryDelay()
{

@JsonProperty ("initialDelay")
public long getInitialDelay()
{
return myInitialDelay;
}
}

@JsonProperty ("initialDelay")
public void setInitialDelay(final Integer initialDelay)
{
this.myInitialDelay = convertToMillis(initialDelay, myUnit);
}
@JsonProperty ("start")
private long myDelay = DEFAULT_DELAY_IN_MS;
@JsonProperty ("max")
private long myMaxDelay = DEFAULT_MAX_DELAY_IN_MS;
@JsonProperty ("unit")
private String myUnit = DEFAULT_TIME_UNIT_IN_SECOND;

@JsonProperty ("fixedDelay")
public long getFixedDelay()
{
return myFixedDelay;
}
@JsonProperty ("start")
public long getStartDelay()
{
return myDelay;
}

@JsonProperty ("fixedDelay")
public void setFixedDelay(final Integer fixedDelay)
{
this.myFixedDelay = convertToMillis(fixedDelay, myUnit);
}
@JsonProperty ("start")
public void setStartDelay(final Long delay)
{
if (delay != null)
{
long convertedDelay = convertToMillis(delay, myUnit);
if (convertedDelay > myMaxDelay)
{
throw new IllegalArgumentException("Start delay cannot be greater than max delay.");
}
this.myDelay = convertToMillis(delay, myUnit);
}
}

private long convertToMillis(final Integer value, final String unit)
{
return switch (unit.toLowerCase(Locale.ENGLISH))
@JsonProperty ("max")
public long getMaxDelay()
{
case "milliseconds" -> value;
case "seconds" -> TimeUnit.SECONDS.toMillis(value);
case "minutes" -> TimeUnit.MINUTES.toMillis(value);
default -> throw new IllegalArgumentException("Unsupported time unit: " + unit);
};
return myMaxDelay;
}

@JsonProperty ("max")
public void setMaxDelay(final Long maxDelay)
{
if (maxDelay != null)
{
long convertedMaxDelay = convertToMillis(maxDelay, myUnit);
if (convertedMaxDelay < myDelay)
{
throw new IllegalArgumentException("Max delay cannot be less than start delay.");
}
this.myMaxDelay = convertToMillis(maxDelay, myUnit);
}
}

@JsonProperty ("unit")
public String getUnit()
{
return myUnit;
}

@JsonProperty ("unit")
public void setUnit(final String unit)
{
if (unit != null && !unit.isBlank())
{
this.myUnit = unit;
this.myDelay = convertToMillis(TimeUnit.MILLISECONDS.toSeconds(this.myDelay), unit);
this.myMaxDelay = convertToMillis(TimeUnit.MILLISECONDS.toSeconds(this.myMaxDelay), unit);
}
}
}

public long currentDelay(final Integer count)
public static final class RetrySchedule
{
long currentDelay = myDelay * count;
if (currentDelay > myMaxDelay)
public RetrySchedule()
{

}

@JsonProperty ("initialDelay")
private long myInitialDelay = DEFAULT_INITIAL_DELAY_IN_MS;
@JsonProperty ("fixedDelay")
private long myFixedDelay = DEFAULT_FIXED_DELAY_IN_MS;
@JsonProperty ("unit")
private String myUnit = DEFAULT_TIME_UNIT_IN_SECOND;

@JsonProperty ("initialDelay")
public long getInitialDelay()
{
return myInitialDelay;
}

@JsonProperty ("initialDelay")
public void setInitialDelay(final Long initialDelay)
{
if (initialDelay != null)
{
this.myInitialDelay = convertToMillis(initialDelay, myUnit);
}
}

@JsonProperty ("fixedDelay")
public long getFixedDelay()
{
return myFixedDelay;
}

@JsonProperty ("fixedDelay")
public void setFixedDelay(final Long fixedDelay)
{
if (fixedDelay != null)
{
this.myFixedDelay = convertToMillis(fixedDelay, myUnit);
}
}

@JsonProperty ("unit")
public String getUnit()
{
currentDelay = myMaxDelay;
return myUnit;
}

@JsonProperty ("unit")
public void setUnit(final String unit)
{
if (unit != null && !unit.isBlank())
{
this.myUnit = unit;
this.myInitialDelay = convertToMillis(TimeUnit.MILLISECONDS.toSeconds(this.myInitialDelay), unit);
this.myFixedDelay = convertToMillis(TimeUnit.MILLISECONDS.toSeconds(this.myFixedDelay), unit);
}

}
return currentDelay;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,27 @@
public final class RetryBackoffStrategy
{
private static final Logger LOG = LoggerFactory.getLogger(RetryBackoffStrategy.class);
private static final int MILLISECONDS_1000 = 1000;
private static final int ONE_SECOND_IN_MS = 1000;
private static final int RETRY_DELAY_MULTIPLIER = 2;
private final RetryPolicyConfig myRetryPolicyConfig;
private final RetryPolicyConfig.RetrySchedule myRetrySchedule;
private final RetryPolicyConfig.RetryDelay myRetryDelay;

public RetryBackoffStrategy(final RetryPolicyConfig retryPolicyConfig)
{
this.myRetryPolicyConfig = retryPolicyConfig;
myRetryPolicyConfig = retryPolicyConfig;
myRetrySchedule = retryPolicyConfig.getRetrySchedule();
myRetryDelay = retryPolicyConfig.getRetryDelay();
}

public long getInitialDelay()
{
return myRetryPolicyConfig.getInitialDelay();
return myRetrySchedule.getInitialDelay();
}

public long getFixedDelay()
{
return myRetryPolicyConfig.getFixedDelay();
return myRetrySchedule.getFixedDelay();
}

public int getMaxAttempts()
Expand All @@ -46,10 +51,10 @@ public int getMaxAttempts()

public long calculateDelay(final int attempt)
{
long baseDelay = myRetryPolicyConfig.getDelay();
long calculatedDelay = baseDelay * (attempt * 2L);
long baseDelay = myRetryDelay.getStartDelay();
long calculatedDelay = baseDelay * ((long) attempt * RETRY_DELAY_MULTIPLIER);
LOG.debug("Calculated delay for attempt {}: {} ms", attempt, calculatedDelay);
return Math.min(calculatedDelay, myRetryPolicyConfig.getMaxDelay() * MILLISECONDS_1000);
return Math.min(calculatedDelay, myRetryDelay.getMaxDelay() * ONE_SECOND_IN_MS);
}

public void sleepBeforeNextRetry(final long delayMillis)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,19 @@ public void startScheduler()
long initialDelay = retryBackoffStrategy.getInitialDelay();
long fixedDelay = retryBackoffStrategy.getFixedDelay();

LOG.info("Starting RetrySchedulerService with initialDelay={} ms and fixedDelay={} ms", initialDelay, fixedDelay);
LOG.debug("Starting RetrySchedulerService with initialDelay={} ms and fixedDelay={} ms", initialDelay, fixedDelay);

myScheduler.scheduleWithFixedDelay(this::retryNodes, initialDelay, fixedDelay, TimeUnit.MILLISECONDS);
}

@VisibleForTesting
void retryNodes()
{
LOG.debug("Retrying unavailable nodes");
LOG.warn("Retrying unavailable nodes");
List<Node> unavailableNodes = findUnavailableNodes();

if (unavailableNodes.isEmpty())
{
LOG.info("No unavailable nodes found.");
return;
}

Expand Down Expand Up @@ -149,7 +148,7 @@ private void retryConnectionForNode(final Node node)
private boolean tryReconnectToNode(final Node node, final UUID nodeId, final int attempt)
{
long delayMillis = retryBackoffStrategy.calculateDelay(attempt);
LOG.info("Attempting to reconnect to node: {}, attempt: {}", nodeId, attempt);
LOG.warn("Attempting to reconnect to node: {}, attempt: {}", nodeId, attempt);

if (establishConnectionToNode(node))
{
Expand Down
Loading

0 comments on commit 7413d73

Please sign in to comment.