PeerGroup: migrate connection retry logic to java.time API

This commit is contained in:
Andreas Schildbach 2023-03-10 15:53:25 +01:00
parent da8b9ce434
commit 85cc162642
3 changed files with 46 additions and 12 deletions

View File

@ -108,6 +108,20 @@ public class TimeUtils {
return time1.isBefore(time2) ? time1 : time2;
}
/**
* Determines the later of two instants.
*/
public static Instant later(Instant time1, Instant time2) {
return time1.isAfter(time2) ? time1 : time2;
}
/**
* Determines the longest of two durations.
*/
public static Duration longest(Duration duration1, Duration duration2) {
return duration1.compareTo(duration2) > 0 ? duration1 : duration2;
}
/**
* Formats a given date+time value to an ISO 8601 string.
* @param dateTime value to format, as a Date

View File

@ -534,7 +534,7 @@ public class PeerGroup implements TransactionBroadcaster {
private Runnable triggerConnectionsJob = new Runnable() {
private boolean firstRun = true;
private final static long MIN_PEER_DISCOVERY_INTERVAL = 1000L;
private final Duration MIN_PEER_DISCOVERY_INTERVAL = Duration.ofSeconds(1);
@Override
public void run() {
@ -549,7 +549,7 @@ public class PeerGroup implements TransactionBroadcaster {
if (!vRunning) return;
boolean doDiscovery = false;
long now = TimeUtils.currentTimeMillis();
Instant now = TimeUtils.currentTime();
lock.lock();
try {
// First run: try and use a local node if there is one, for the additional security it can provide.
@ -562,7 +562,7 @@ public class PeerGroup implements TransactionBroadcaster {
return;
}
boolean havePeerWeCanTry = !inactives.isEmpty() && backoffMap.get(inactives.peek()).getRetryTime() <= now;
boolean havePeerWeCanTry = !inactives.isEmpty() && backoffMap.get(inactives.peek()).getRetryInstant().isBefore(now);
doDiscovery = !havePeerWeCanTry;
} finally {
firstRun = false;
@ -589,10 +589,10 @@ public class PeerGroup implements TransactionBroadcaster {
// Inactives is sorted by backoffMap time.
if (inactives.isEmpty()) {
if (countConnectedAndPendingPeers() < getMaxConnections()) {
long interval = Math.max(groupBackoff.getRetryTime() - now, MIN_PEER_DISCOVERY_INTERVAL);
Duration interval = TimeUtils.longest(Duration.between(now, groupBackoff.getRetryInstant()), MIN_PEER_DISCOVERY_INTERVAL);
log.info("Peer discovery didn't provide us any more peers, will try again in "
+ interval + "ms.");
executor.schedule(this, interval, TimeUnit.MILLISECONDS);
+ interval.toMillis() + " ms.");
executor.schedule(this, interval.toMillis(), TimeUnit.MILLISECONDS);
} else {
// We have enough peers and discovery provided no more, so just settle down. Most likely we
// were given a fixed set of addresses in some test scenario.
@ -608,13 +608,13 @@ public class PeerGroup implements TransactionBroadcaster {
// Most likely we were given a fixed set of addresses in some test scenario.
return;
}
long retryTime = backoffMap.get(addrToTry).getRetryTime();
retryTime = Math.max(retryTime, groupBackoff.getRetryTime());
if (retryTime > now) {
long delay = retryTime - now;
log.info("Waiting {} ms before next connect attempt to {}", delay, addrToTry);
Instant retryTime = backoffMap.get(addrToTry).getRetryInstant();
retryTime = TimeUtils.later(retryTime, groupBackoff.getRetryInstant());
if (retryTime.isAfter(now)) {
Duration delay = Duration.between(now, retryTime);
log.info("Waiting {} ms before next connect attempt to {}", delay.toMillis(), addrToTry);
inactives.add(addrToTry);
executor.schedule(this, delay, TimeUnit.MILLISECONDS);
executor.schedule(this, delay.toMillis(), TimeUnit.MILLISECONDS);
return;
}
connectTo(addrToTry, false, vConnectTimeoutMillis);

View File

@ -58,4 +58,24 @@ public class TimeUtilsTest {
assertEquals(t1, TimeUtils.earlier(t1, t1));
assertEquals(t2, TimeUtils.earlier(t2, t2));
}
@Test
public void later() {
Instant t1 = Instant.now(); // earlier
Instant t2 = t1.plusSeconds(1); // later
assertEquals(t2, TimeUtils.later(t1, t2));
assertEquals(t2, TimeUtils.later(t2, t1));
assertEquals(t1, TimeUtils.later(t1, t1));
assertEquals(t2, TimeUtils.later(t2, t2));
}
@Test
public void longest() {
Duration d1 = Duration.ofMinutes(1); // shorter
Duration d2 = Duration.ofMinutes(1); // longer
assertEquals(d2, TimeUtils.longest(d1, d2));
assertEquals(d2, TimeUtils.longest(d2, d1));
assertEquals(d1, TimeUtils.longest(d1, d1));
assertEquals(d2, TimeUtils.longest(d2, d2));
}
}