Skip to content

Commit

Permalink
bug fix - V1 canHandle() should cater maxWaitTime (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
jayjlu authored Apr 29, 2024
1 parent 91f977c commit a42e54e
Show file tree
Hide file tree
Showing 14 changed files with 75 additions and 13 deletions.
12 changes: 6 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,24 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
<version>2.0.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.9</version>
<version>2.0.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.muserver</groupId>
<artifactId>mu-server</artifactId>
<version>0.74.3</version>
<version>1.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
<version>20240303</version>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -90,7 +90,7 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.1</version>
<version>5.10.2</version>
<scope>test</scope>
</dependency>

Expand All @@ -109,7 +109,7 @@
<dependency>
<groupId>com.hsbc.cranker</groupId>
<artifactId>cranker-connector</artifactId>
<version>1.2.3</version>
<version>1.2.4</version>
<scope>test</scope>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@
public interface ConnectorConnection {

/**
* A unique ID of this socket
* @return A unique ID of this socket
*/
String socketID();

/**
* The port the socket is connected on
* @return The port the socket is connected on
*/
int port();

/**
* the data in this object as a map
* @return Returns the data in this object as a map
*/
HashMap<String, Object> toMap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,31 @@
public interface ConnectorInstance {

/**
* The IP address of the instance.
* @return The IP address of the instance.
*/
String ip();

/**
* The unique ID of the connector.
* @return The unique ID of the connector.
*/
String connectorInstanceID();

/**
* The current idle connections that this connector has registered to the router.
* @return The current idle connections that this connector has registered to the router.
*/
List<ConnectorConnection> connections();

/**
* Dark mode status
* @return Returns <code>true</code> if this connector is on a dark mode host; otherwise <code>false</code>.
*/
boolean darkMode();

/**
* The state of this object as a map of key-value pairs.
* @return Returns the state of this object as a map of key-value pairs.
*/
Map<String,Object> toMap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,32 @@
public interface ConnectorService {

/**
* The path prefix of the service.
* @return The path prefix of the service, or &quot;*&quot; if it is a catch-all service.
* @see #isCatchAll()
*/
String route();

/**
* The component name that the connector registered
* @return The component name that the connector registered
*/
String componentName();

/**
* The connectors that serve this route.
* @return The connectors that serve this route.
*/
List<ConnectorInstance> connectors();

/**
* If this connector serves from the root of the URL path.
* @return True if this connector serves from the root of the URL path
*/
boolean isCatchAll();

/**
* Gets this data has key-value pairs.
* @return Gets this data has key-value pairs.
*/
Map<String,Object> toMap();
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/com/hsbc/cranker/mucranker/CrankerRouter.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public interface CrankerRouter {
MuHandler createRegistrationHandler();

/**
* The total number of websocket connections for all routes that are currently connected and ready to receive requests
* @return The total number of websocket connections for all routes that are currently connected and ready to receive requests
*/
int idleConnectionCount();
Expand All @@ -40,11 +41,13 @@ public interface CrankerRouter {
void stop();

/**
* A manager that allows you to stop or start requests going to specific hosts.
* @return A manager that allows you to stop or start requests going to specific hosts.
*/
DarkModeManager darkModeManager();

/**
* The version of mu-cranker-router being used.
* @return The version of mu-cranker-router being used, e.g. <code>1.0.0</code>
*/
static String muCrankerVersion() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ public class CrankerRouterBuilder {
private RouteResolver routeResolver;
private List<String> supportedCrankerProtocol = List.of("1.0", "3.0");

private CrankerRouterBuilder() {}

/**
* Create a CrankerRouterBuilder
* @return A new builder
*/
public static CrankerRouterBuilder crankerRouter() {
Expand Down Expand Up @@ -225,6 +228,7 @@ public CrankerRouterBuilder withSupportedCrankerProtocols(List<String> protocols


/**
* Create a newly created CrankerRouter object
* @return A newly created CrankerRouter object
*/
public CrankerRouter start() {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/hsbc/cranker/mucranker/DarkHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
public interface DarkHost {

/**
* The address of the host
* @return The address of the host
*/
InetAddress address();

/**
* The time that dark mode was turned on for this host
* @return Returns the time that dark mode was turned on for this host
*/
Instant dateEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
*/
public class LongestFirstRouteResolver implements RouteResolver{

/**
* Constructor for LongestFirstRouteResolver
*/
public LongestFirstRouteResolver() {}

/**
* Algorithm: using the longest route to match from the existing routes.
*
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/hsbc/cranker/mucranker/ProxyInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,55 @@
public interface ProxyInfo {

/**
* isCatchAll
* @return Returns true if the connector is a catch-all connector (i.e. the router of the connector is '*').
*/
boolean isCatchAll();

/**
* A unique ID for the service connector.
* @return A unique ID for the service connector.
*/
String connectorInstanceID();

/**
* The address of the service connector that this request is being proxied to.
* @return The address of the service connector that this request is being proxied to.
*/
InetSocketAddress serviceAddress();

/**
* The cranker route (i.e. the first part of a path) for the request, or '*' if a catch-all connector is used.
* @return The cranker route (i.e. the first part of a path) for the request, or '*' if a catch-all connector is used.
*/
String route();

/**
* The client's request to the router.
* @return The client's request to the router.
*/
MuRequest request();

/**
* The router's response to the client.
* @return The router's response to the client.
*/
MuResponse response();

/**
* The time in millis from when the router received the request until it sent the last response byte.
* @return The time in millis from when the router received the request until it sent the last response byte.
*/
long durationMillis();

/**
* The number of bytes uploaded by the client in the request
* @return The number of bytes uploaded by the client in the request
*/
long bytesReceived();

/**
* The number of bytes sent to the client on the response
* @return The number of bytes sent to the client on the response
*/
long bytesSent();
Expand All @@ -73,6 +82,7 @@ public interface ProxyInfo {
Throwable errorIfAny();

/**
* Wait time in millis seconds to get a websocket (which is used for proxy requests)
* @return wait time in millis seconds to get a websocket (which is used for proxy requests)
*/
long socketWaitInMillis();
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/hsbc/cranker/mucranker/RouterInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
public interface RouterInfo {

/**
* All the services that are registered with this cranker
* @return All the services that are registered with this cranker
*/
List<ConnectorService> services();
Expand All @@ -32,6 +33,7 @@ public interface RouterInfo {
Map<String, Object> toMap();

/**
* All the hosts that this router currently will not send requests to
* @return All the hosts that this router currently will not send requests to
*/
Set<DarkHost> darkHosts();
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/com/hsbc/cranker/mucranker/WebSocketFarm.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void cleanRoutes(long routesKeepTimeMillis) {
final long cutoffTime = System.currentTimeMillis() - routesKeepTimeMillis;
this.sockets.entrySet().stream()
.filter(entry -> entry.getValue() != null
&& entry.getValue().size() == 0
&& entry.getValue().isEmpty()
&& routeLastRemovalTimes.containsKey(entry.getKey())
&& routeLastRemovalTimes.get(entry.getKey()) < cutoffTime)
.forEach(entry -> {
Expand All @@ -75,7 +75,9 @@ public boolean canHandle(String target, boolean useCatchAll) {
final String routeKey = resolveRouteKey(target, useCatchAll);
if (routeKey == null) return false;
final Queue<RouterSocket> routerSockets = sockets.get(routeKey);
return routerSockets != null && routerSockets.size() > 0;
if (routerSockets != null && !routerSockets.isEmpty()) return true;
return routeLastRemovalTimes.containsKey(routeKey)
&& (System.currentTimeMillis() - routeLastRemovalTimes.get(routeKey) < this.maxWaitInMillis);
}

public int idleCount() {
Expand Down Expand Up @@ -112,7 +114,7 @@ private void addWebSocketSync(String route, RouterSocket socket) {

// if there are requests waiting for a socket to this route, then immediately pass the socket to the request
final Queue<WaitingSocketTask> waiting = waitingTasks.get(route);
if (waiting != null && waiting.size() > 0) {
if (waiting != null && !waiting.isEmpty()) {
final WaitingSocketTask waitTask = waiting.poll();
if (waitTask != null) {
waitTask.notifySuccess(socket);
Expand Down Expand Up @@ -253,7 +255,7 @@ static void logIfFail(ThrowingFunction f) {
}
}

private class WaitingSocketTask {
private static class WaitingSocketTask {

private final String target;
private Consumer<RouterSocket> successListener;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/hsbc/cranker/mucranker/WebSocketFarmV3.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void cleanRoutes(long routesKeepTimeMillis) {
final long cutoffTime = System.currentTimeMillis() - routesKeepTimeMillis;
this.sockets.entrySet().stream()
.filter(entry -> entry.getValue() != null
&& entry.getValue().size() == 0
&& entry.getValue().isEmpty()
&& routeLastRemovalTimes.containsKey(entry.getKey())
&& routeLastRemovalTimes.get(entry.getKey()) < cutoffTime)
.forEach(entry -> {
Expand All @@ -63,7 +63,7 @@ public boolean canHandle(String target, boolean useCatchAll) {
final String routeKey = resolveRouteKey(target, useCatchAll);
if (routeKey == null) return false;
final List<RouterSocketV3> routeSockets = sockets.get(routeKey);
return routeSockets != null && routeSockets.size() > 0;
return routeSockets != null && !routeSockets.isEmpty();
}

private String resolveRouteKey(String target, boolean useCatchAll) {
Expand Down Expand Up @@ -128,7 +128,7 @@ public CompletableFuture<RouterSocketV3> getWebSocket(String target, boolean use
}
List<RouterSocketV3> routeSockets = sockets.get(routeKey);

if (routeSockets == null || routeSockets.size() == 0) {
if (routeSockets == null || routeSockets.isEmpty()) {
future.complete(null);
return;
}
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/RunLocal.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.json.JSONObject;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

Expand All @@ -17,6 +18,7 @@ public static void main(String[] args) throws IOException {

// Use the mu-cranker-router builder to create a router object.
CrankerRouter router = CrankerRouterBuilder.crankerRouter()
.withSupportedCrankerProtocols(List.of("cranker_3.0", "cranker_1.0"))
.withIdleTimeout(5, TimeUnit.MINUTES)
.withRegistrationIpValidator(ip -> true)
.start();
Expand Down
19 changes: 19 additions & 0 deletions src/test/java/com/hsbc/cranker/mucranker/MultiConnectorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,25 @@ void connectorCanDistributedToDifferentConnector_V1useCatchAll_V3useSpecificRout
assertThat(bodyMap.get("targetV3_1").get(), is(20));
}

@Test
void connectorCanDistributedToDifferentConnector_V3useCatchAll_V1useSpecificRouteTakeHigherPriority() {
// start v1 connector
targetV1_1 = httpServer()
.addHandler(Method.GET, "/my-service/hello", (request, response, pathParams) -> response.write("targetV1_1"))
.start();
connectorV1_1 = startConnector("*", "my-service", targetV1_1, List.of("cranker_1.0"));

// start another v3 connector
targetV3_1 = httpServer()
.addHandler(Method.GET, "/my-service/hello", (request, response, pathParams) -> response.write("targetV3_1"))
.start();
connectorV3_1 = startConnector("*", "*", targetV3_1, List.of("cranker_3.0"));

// specific route take higher priority
final HashMap<String, AtomicInteger> bodyMap = callAndGroupByBody(router.uri().resolve("/my-service/hello"), 20, 1);
assertThat(bodyMap.get("targetV1_1").get(), is(20));
}

@Test
void connectorCanDistributedToDifferentConnector_V1useSpecificRouteTakeHigherPriority_V3useCatchAll() {
// start v1 connector
Expand Down

0 comments on commit a42e54e

Please sign in to comment.