Improved server resilience with registry connection.

This commit is contained in:
Andrew Lalis 2021-07-07 12:20:06 +02:00
parent 6df046dfea
commit fa8c553041
2 changed files with 34 additions and 13 deletions

View File

@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
@ -26,6 +25,14 @@ import java.util.concurrent.TimeUnit;
* date with this server's information, by sending periodic update HTTP messages. * date with this server's information, by sending periodic update HTTP messages.
*/ */
public class RegistryManager { public class RegistryManager {
/**
* The list of retry timings that will be used if the registry server cannot
* be reached. Using the retryTimingIndex, we'll start at 5, and increment
* each time the connection fails.
*/
public static final long[] RETRY_TIMINGS = new long[]{5, 10, 30, 60, 120, 300};
private int retryTimingIndex = 0;
private final ScheduledExecutorService executorService; private final ScheduledExecutorService executorService;
private final Server server; private final Server server;
@ -36,10 +43,7 @@ public class RegistryManager {
this.server = server; this.server = server;
this.mapper = new ObjectMapper(); this.mapper = new ObjectMapper();
this.executorService = Executors.newScheduledThreadPool(3); this.executorService = Executors.newScheduledThreadPool(3);
this.httpClient = HttpClient.newBuilder() this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(3)).build();
.executor(this.executorService)
.connectTimeout(Duration.ofSeconds(3))
.build();
this.executorService.submit(this::sendInfo); this.executorService.submit(this::sendInfo);
this.executorService.scheduleAtFixedRate( this.executorService.scheduleAtFixedRate(
this::sendUpdate, this::sendUpdate,
@ -64,7 +68,23 @@ public class RegistryManager {
.POST(HttpRequest.BodyPublishers.ofByteArray(this.mapper.writeValueAsBytes(data))) .POST(HttpRequest.BodyPublishers.ofByteArray(this.mapper.writeValueAsBytes(data)))
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.build(); .build();
this.httpClient.sendAsync(request, HttpResponse.BodyHandlers.discarding()); try {
System.out.println("Sending server information to registry...");
var response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
System.err.println("Non-OK status when sending registry info:\n" + response.body() + "\nAttempting to send again in 10 seconds...");
this.executorService.schedule(this::sendInfo, 10, TimeUnit.SECONDS);
} else if (this.retryTimingIndex > 0) {
this.retryTimingIndex = 0; // Reset the retry timing index if we successfully sent our server info.
}
} catch (IOException e) {
long retryTiming = RETRY_TIMINGS[this.retryTimingIndex];
System.err.println("Could not send info to registry server. Registry may be offline, or this server may not have internet access. Attempting to resend info in " + retryTiming + " seconds...");
this.executorService.schedule(this::sendInfo, retryTiming, TimeUnit.SECONDS);
if (this.retryTimingIndex < RETRY_TIMINGS.length - 1) {
this.retryTimingIndex++;
}
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -81,13 +101,14 @@ public class RegistryManager {
.PUT(HttpRequest.BodyPublishers.ofByteArray(this.mapper.writeValueAsBytes(data))) .PUT(HttpRequest.BodyPublishers.ofByteArray(this.mapper.writeValueAsBytes(data)))
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.build(); .build();
this.httpClient.sendAsync(request, responseInfo -> { try {
if (responseInfo.statusCode() != 200) { var response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Received non-OK status when sending registry update. Re-sending registry info..."); if (response.statusCode() != 200) {
this.sendInfo(); System.err.println("Received non-OK status when sending registry update:\n" + response.body());
}
} catch (IOException e) {
System.err.println("Error sending update to registry server: " + e);
} }
return null;
});
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -19,7 +19,7 @@ registry-settings:
# The URI which points to the registry server. This is only used if discoverable is true. # The URI which points to the registry server. This is only used if discoverable is true.
registry-uri: "http://localhost:8567" registry-uri: "http://localhost:8567"
# How often to send status updates to the registry server, in seconds. # How often to send status updates to the registry server, in seconds.
update-interval: 10 update-interval: 30
# The name of this server. # The name of this server.
name: "Testing Server" name: "Testing Server"
# The address that clients can use to connect to this server. # The address that clients can use to connect to this server.