diff --git a/src/main/java/com/hsbc/cranker/connector/ConnectorSocket.java b/src/main/java/com/hsbc/cranker/connector/ConnectorSocket.java index df5ad95..e2fc5a3 100644 --- a/src/main/java/com/hsbc/cranker/connector/ConnectorSocket.java +++ b/src/main/java/com/hsbc/cranker/connector/ConnectorSocket.java @@ -60,6 +60,7 @@ enum State { } /** + * completion state * @return true if it's in end state */ public boolean isCompleted() { @@ -68,11 +69,13 @@ public boolean isCompleted() { } /** + * connection state * @return The current state of this connection */ State state(); /** + * cranker connection protocol version * @return The connector socket's version, e.g. "cranker_3.0", "cranker_1.0" */ String version(); diff --git a/src/main/java/com/hsbc/cranker/connector/CrankerConnector.java b/src/main/java/com/hsbc/cranker/connector/CrankerConnector.java index 61801eb..121a429 100644 --- a/src/main/java/com/hsbc/cranker/connector/CrankerConnector.java +++ b/src/main/java/com/hsbc/cranker/connector/CrankerConnector.java @@ -41,12 +41,14 @@ public interface CrankerConnector { boolean stop(long timeout, TimeUnit timeUnit); /** + * connectorId * @return A unique ID assigned to this connector that is provided to the router for diagnostic reasons. */ String connectorId(); /** - * @return Meta data about the routers that this connector is connected to. Provided for diagnostic purposes. + * list of the router registration + * @return Metadata about the routers that this connector is connected to. Provided for diagnostic purposes. */ List routers(); } diff --git a/src/main/java/com/hsbc/cranker/connector/CrankerConnectorBuilder.java b/src/main/java/com/hsbc/cranker/connector/CrankerConnectorBuilder.java index 1f20712..0641556 100644 --- a/src/main/java/com/hsbc/cranker/connector/CrankerConnectorBuilder.java +++ b/src/main/java/com/hsbc/cranker/connector/CrankerConnectorBuilder.java @@ -15,6 +15,11 @@ */ public class CrankerConnectorBuilder { + /** + * prevent constructing CrankerConnectorBuilder, should use CrankerConnectorBuilder.connector() instead. + */ + private CrankerConnectorBuilder() {} + /** * cranker protocol 1.0 */ @@ -241,6 +246,7 @@ public static HttpClient.Builder createHttpClient(boolean trustAll) { } /** + * constructing a new connector builder * @return A new connector builder */ public static CrankerConnectorBuilder connector() { diff --git a/src/main/java/com/hsbc/cranker/connector/RegistrationUriSuppliers.java b/src/main/java/com/hsbc/cranker/connector/RegistrationUriSuppliers.java index d36e96d..5c5c19d 100644 --- a/src/main/java/com/hsbc/cranker/connector/RegistrationUriSuppliers.java +++ b/src/main/java/com/hsbc/cranker/connector/RegistrationUriSuppliers.java @@ -19,6 +19,11 @@ */ public class RegistrationUriSuppliers { + /** + * preventing constructing RegistrationUriSuppliers, as it's a util class. + */ + private RegistrationUriSuppliers() {} + /** * Creates a supplier that always returns a fixed set of URIs * @param uris The URIs to return, in the format wss://crankerrouter.example.org diff --git a/src/main/java/com/hsbc/cranker/connector/RouterEventListener.java b/src/main/java/com/hsbc/cranker/connector/RouterEventListener.java index c0a9345..4a56eb8 100644 --- a/src/main/java/com/hsbc/cranker/connector/RouterEventListener.java +++ b/src/main/java/com/hsbc/cranker/connector/RouterEventListener.java @@ -38,6 +38,7 @@ class ChangeData { private final List unchanged; /** + * The routers that have been newly registered * @return The routers that have been newly registered */ public List added() { @@ -45,6 +46,7 @@ public List added() { } /** + * The routers that are no longer being connected to * @return The routers that are no longer being connected to */ public List removed() { @@ -52,6 +54,7 @@ public List removed() { } /** + * The routers that remain unchanged * @return The routers that remain unchanged */ public List unchanged() { diff --git a/src/main/java/com/hsbc/cranker/connector/RouterRegistration.java b/src/main/java/com/hsbc/cranker/connector/RouterRegistration.java index 0b1b043..60c26c7 100644 --- a/src/main/java/com/hsbc/cranker/connector/RouterRegistration.java +++ b/src/main/java/com/hsbc/cranker/connector/RouterRegistration.java @@ -5,13 +5,11 @@ import java.net.http.WebSocket; import java.time.Duration; import java.util.Collection; -import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -21,26 +19,31 @@ public interface RouterRegistration { /** + * The number of expected idle connections to this router * @return The number of expected idle connections to this router */ int expectedWindowSize(); /** + * The current number of idle connections * @return The current number of idle connections */ int idleSocketSize(); /** + * The sockets that are currently connected to the router, ready to process a request * @return The sockets that are currently connected to the router, ready to process a request */ Collection idleSockets(); /** + * The router's websocket registration URI * @return The router's websocket registration URI */ URI registrationUri(); /** + * The current state of the connection to this router * @return The current state of the connection to this router */ State state(); @@ -54,6 +57,7 @@ public interface RouterRegistration { int currentUnsuccessfulConnectionAttempts(); /** + * last connection error * @return If this socket is not connected due to an error, then this is the reason; otherwise this is null. */ Throwable lastConnectionError(); @@ -172,6 +176,16 @@ private static String[] getLessPreferredProtocol(List protocols) { return protocols.size() > 1 ? protocols.subList(1, protocols.size()).toArray(new String[0]) : new String[0]; } + private void addAnythingMissingWithBackoff() { + if (isAddMissingScheduled.compareAndSet(false, true)) { + int attempts = connectAttempts.incrementAndGet(); + executor.schedule(() -> { + isAddMissingScheduled.set(false); + addAnyMissing(); + }, retryAfterMillis(attempts), TimeUnit.MILLISECONDS); + } + } + private void addAnyMissing() { while (state == State.ACTIVE && idleSockets.size() < windowSize) { @@ -200,13 +214,7 @@ private void addAnyMissing() { if (routerEventListener != null) { routerEventListener.onSocketConnectionError(this, throwable); } - if (isAddMissingScheduled.compareAndSet(false, true)) { - connectAttempts.incrementAndGet(); - executor.schedule(() -> { - isAddMissingScheduled.set(false); - addAnyMissing(); - }, retryAfterMillis(), TimeUnit.MILLISECONDS); - } + addAnythingMissingWithBackoff(); } }); } @@ -214,9 +222,10 @@ private void addAnyMissing() { /** * @return Milliseconds to wait until trying again, increasing exponentially, capped at 10 seconds + * @param retryAttempts retry attempts */ - private int retryAfterMillis() { - return 500 + Math.min(10000, (int) Math.pow(2, connectAttempts.get())); + private static int retryAfterMillis(int retryAttempts) { + return 500 + Math.min(10000, (int) Math.pow(2, retryAttempts)); } @Override @@ -230,7 +239,11 @@ public void onConnectionAcquired(ConnectorSocket socket) { public void onClose(ConnectorSocket socket, Throwable error) { runningSockets.remove(socket); idleSockets.remove(socket); - addAnyMissing(); + if (error == null) { + addAnyMissing(); + } else { + addAnythingMissingWithBackoff(); + } } @Override