diff --git a/pom.xml b/pom.xml
index 11d1d18d..f148fbd2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
io.appform.ranger
ranger
pom
- 1.1-RC5
+ 1.2-RC5
Ranger
https://github.com/appform-io/ranger
Service Discovery for Java
diff --git a/ranger-client/pom.xml b/ranger-client/pom.xml
index 064f474b..1eeb8203 100644
--- a/ranger-client/pom.xml
+++ b/ranger-client/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0
diff --git a/ranger-core/pom.xml b/ranger-core/pom.xml
index f4605de4..901fc29f 100644
--- a/ranger-core/pom.xml
+++ b/ranger-core/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0
diff --git a/ranger-core/src/main/java/io/appform/ranger/core/finder/BaseServiceFinderBuilder.java b/ranger-core/src/main/java/io/appform/ranger/core/finder/BaseServiceFinderBuilder.java
index 23859a41..de9a9746 100644
--- a/ranger-core/src/main/java/io/appform/ranger/core/finder/BaseServiceFinderBuilder.java
+++ b/ranger-core/src/main/java/io/appform/ranger/core/finder/BaseServiceFinderBuilder.java
@@ -18,10 +18,15 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
-import io.appform.ranger.core.finder.nodeselector.RandomServiceNodeSelector;
+import io.appform.ranger.core.finder.nodeselector.WeightedRandomServiceNodeSelector;
import io.appform.ranger.core.finder.serviceregistry.ServiceRegistryUpdater;
import io.appform.ranger.core.finder.serviceregistry.signal.ScheduledRegistryUpdateSignal;
-import io.appform.ranger.core.model.*;
+import io.appform.ranger.core.model.Deserializer;
+import io.appform.ranger.core.model.NodeDataSource;
+import io.appform.ranger.core.model.Service;
+import io.appform.ranger.core.model.ServiceNodeSelector;
+import io.appform.ranger.core.model.ServiceRegistry;
+import io.appform.ranger.core.model.ShardSelector;
import io.appform.ranger.core.signals.Signal;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
@@ -48,7 +53,7 @@ public abstract class BaseServiceFinderBuilder
protected boolean disablePushUpdaters;
protected D deserializer;
protected ShardSelector shardSelector;
- protected ServiceNodeSelector nodeSelector = new RandomServiceNodeSelector<>();
+ protected ServiceNodeSelector nodeSelector = new WeightedRandomServiceNodeSelector<>();
protected final List> additionalRefreshSignals = new ArrayList<>();
protected final List> startSignalHandlers = Lists.newArrayList();
protected final List> stopSignalHandlers = Lists.newArrayList();
diff --git a/ranger-core/src/main/java/io/appform/ranger/core/finder/nodeselector/WeightedRandomServiceNodeSelector.java b/ranger-core/src/main/java/io/appform/ranger/core/finder/nodeselector/WeightedRandomServiceNodeSelector.java
new file mode 100644
index 00000000..48a48566
--- /dev/null
+++ b/ranger-core/src/main/java/io/appform/ranger/core/finder/nodeselector/WeightedRandomServiceNodeSelector.java
@@ -0,0 +1,36 @@
+package io.appform.ranger.core.finder.nodeselector;
+
+import io.appform.ranger.core.model.ServiceNode;
+import io.appform.ranger.core.model.ServiceNodeSelector;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class WeightedRandomServiceNodeSelector implements ServiceNodeSelector {
+
+ @Override
+ public ServiceNode select(List> serviceNodes) {
+ if (serviceNodes == null || serviceNodes.isEmpty()) {
+ throw new IllegalArgumentException("Service nodes list cannot be empty");
+ }
+
+ double totalWeight = 0.0;
+ double[] cumulativeWeights = new double[serviceNodes.size()];
+
+ for (int i = 0; i < serviceNodes.size(); i++) {
+ totalWeight += serviceNodes.get(i).getWeight();
+ cumulativeWeights[i] = totalWeight;
+ }
+
+ double randomValue = ThreadLocalRandom.current().nextDouble(totalWeight);
+
+
+ int index = Arrays.binarySearch(cumulativeWeights, randomValue);
+ if (index < 0) {
+ index = -index - 1;
+ }
+
+ return serviceNodes.get(index);
+ }
+}
diff --git a/ranger-core/src/main/java/io/appform/ranger/core/model/ServiceNode.java b/ranger-core/src/main/java/io/appform/ranger/core/model/ServiceNode.java
index 05a41df1..7707488f 100644
--- a/ranger-core/src/main/java/io/appform/ranger/core/model/ServiceNode.java
+++ b/ranger-core/src/main/java/io/appform/ranger/core/model/ServiceNode.java
@@ -28,6 +28,8 @@
public class ServiceNode {
private String host;
private int port;
+ @Builder.Default
+ private double weight = 1.0;
private T nodeData;
@Builder.Default
private HealthcheckStatus healthcheckStatus = HealthcheckStatus.healthy;
@@ -37,6 +39,18 @@ public class ServiceNode {
@Builder.Default
private String portScheme = PortSchemes.HTTP;
+ public ServiceNode(final String host, final int port, final T nodeData, final HealthcheckStatus healthcheckStatus,
+ final long lastUpdatedTimeStamp,
+ final String portScheme) {
+ this.host = host;
+ this.port = port;
+ this.weight = 1;
+ this.nodeData = nodeData;
+ this.healthcheckStatus = healthcheckStatus;
+ this.lastUpdatedTimeStamp = lastUpdatedTimeStamp;
+ this.portScheme = portScheme;
+ }
+
public String representation() {
return String.format("%s:%d", host, port);
}
diff --git a/ranger-core/src/main/java/io/appform/ranger/core/serviceprovider/ServiceProvider.java b/ranger-core/src/main/java/io/appform/ranger/core/serviceprovider/ServiceProvider.java
index 08f7db50..8985625c 100644
--- a/ranger-core/src/main/java/io/appform/ranger/core/serviceprovider/ServiceProvider.java
+++ b/ranger-core/src/main/java/io/appform/ranger/core/serviceprovider/ServiceProvider.java
@@ -26,6 +26,7 @@
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
+import java.lang.management.ManagementFactory;
import java.util.Collections;
import java.util.List;
@@ -69,10 +70,23 @@ private void handleHealthUpdate(HealthcheckResult result) {
log.debug("No update to health state of node. Skipping data source update.");
return;
}
+
+ serviceNode.setWeight(computeWeight());// to be updated
serviceNode.setHealthcheckStatus(result.getStatus());
serviceNode.setLastUpdatedTimeStamp(result.getUpdatedTime());
dataSink.updateState(serializer, serviceNode);
log.debug("Updated node with health check result: {}", result);
}
+ private double computeWeight() {
+ double T = 60000; // Midpoint at 5 minutes
+ double S = 30000; // Scaling factor
+
+ return 1.0 / (1.0 + Math.exp(-( (getInstanceUptime() - T) / S )));
+ }
+
+ private long getInstanceUptime() {
+ return ManagementFactory.getRuntimeMXBean().getUptime();
+ }
+
}
diff --git a/ranger-core/src/test/java/io/appform/ranger/core/finderhub/ServiceFinderHubTest.java b/ranger-core/src/test/java/io/appform/ranger/core/finderhub/ServiceFinderHubTest.java
index 3d1d1d36..caaa9965 100644
--- a/ranger-core/src/test/java/io/appform/ranger/core/finderhub/ServiceFinderHubTest.java
+++ b/ranger-core/src/test/java/io/appform/ranger/core/finderhub/ServiceFinderHubTest.java
@@ -186,7 +186,8 @@ private static class TestNodeDataSource implements NodeDataSource>> refresh(Deserializer deserializer) {
val list = new ArrayList>();
- list.add(new ServiceNode<>("HOST", 0, TestNodeData.builder().shardId(1).build(), HealthcheckStatus.healthy, Long.MAX_VALUE, "HTTP"));
+ list.add(new ServiceNode<>("HOST", 0, 1f, TestNodeData.builder().shardId(1).build(),
+ HealthcheckStatus.healthy, Long.MAX_VALUE, "HTTP"));
return Optional.of(list);
}
diff --git a/ranger-discovery-bundle/pom.xml b/ranger-discovery-bundle/pom.xml
index 58bf1bcd..e7e8d82c 100644
--- a/ranger-discovery-bundle/pom.xml
+++ b/ranger-discovery-bundle/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0
diff --git a/ranger-drove-client/pom.xml b/ranger-drove-client/pom.xml
index 155cbbd4..0a70ca39 100644
--- a/ranger-drove-client/pom.xml
+++ b/ranger-drove-client/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0
diff --git a/ranger-drove-client/src/main/java/io/appform/ranger/client/drove/AbstractRangerDroveHubClient.java b/ranger-drove-client/src/main/java/io/appform/ranger/client/drove/AbstractRangerDroveHubClient.java
index b205f9d8..80c0c753 100644
--- a/ranger-drove-client/src/main/java/io/appform/ranger/client/drove/AbstractRangerDroveHubClient.java
+++ b/ranger-drove-client/src/main/java/io/appform/ranger/client/drove/AbstractRangerDroveHubClient.java
@@ -16,7 +16,7 @@
package io.appform.ranger.client.drove;
import io.appform.ranger.client.AbstractRangerHubClient;
-import io.appform.ranger.core.finder.nodeselector.RandomServiceNodeSelector;
+import io.appform.ranger.core.finder.nodeselector.WeightedRandomServiceNodeSelector;
import io.appform.ranger.core.finderhub.ServiceDataSource;
import io.appform.ranger.core.finderhub.ServiceFinderHub;
import io.appform.ranger.core.model.ServiceNodeSelector;
@@ -42,7 +42,7 @@ public abstract class AbstractRangerDroveHubClient nodeSelector = new RandomServiceNodeSelector<>();
+ private final ServiceNodeSelector nodeSelector = new WeightedRandomServiceNodeSelector<>();
@Override
protected ServiceDataSource getDefaultDataSource() {
diff --git a/ranger-drove/pom.xml b/ranger-drove/pom.xml
index de64fb73..7a3f0350 100644
--- a/ranger-drove/pom.xml
+++ b/ranger-drove/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
1.30
diff --git a/ranger-drove/src/main/java/io/appform/ranger/drove/serde/DroveResponseDataDeserializer.java b/ranger-drove/src/main/java/io/appform/ranger/drove/serde/DroveResponseDataDeserializer.java
index 53441f4a..b586d75d 100644
--- a/ranger-drove/src/main/java/io/appform/ranger/drove/serde/DroveResponseDataDeserializer.java
+++ b/ranger-drove/src/main/java/io/appform/ranger/drove/serde/DroveResponseDataDeserializer.java
@@ -22,7 +22,9 @@
import lombok.extern.slf4j.Slf4j;
import lombok.val;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
/**
@@ -44,6 +46,7 @@ public final List> deserialize(List appInfo) {
}
return new ServiceNode<>(endpoint.getHost(),
endpoint.getPort(),
+ 1,
info,
HealthcheckStatus.healthy,
currTime,
diff --git a/ranger-http-client/pom.xml b/ranger-http-client/pom.xml
index 048a55f5..849a848d 100644
--- a/ranger-http-client/pom.xml
+++ b/ranger-http-client/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0
diff --git a/ranger-http-client/src/main/java/io/appform/ranger/client/http/AbstractRangerHttpHubClient.java b/ranger-http-client/src/main/java/io/appform/ranger/client/http/AbstractRangerHttpHubClient.java
index 5dd6910b..63466445 100644
--- a/ranger-http-client/src/main/java/io/appform/ranger/client/http/AbstractRangerHttpHubClient.java
+++ b/ranger-http-client/src/main/java/io/appform/ranger/client/http/AbstractRangerHttpHubClient.java
@@ -16,7 +16,7 @@
package io.appform.ranger.client.http;
import io.appform.ranger.client.AbstractRangerHubClient;
-import io.appform.ranger.core.finder.nodeselector.RandomServiceNodeSelector;
+import io.appform.ranger.core.finder.nodeselector.WeightedRandomServiceNodeSelector;
import io.appform.ranger.core.finderhub.ServiceDataSource;
import io.appform.ranger.core.finderhub.ServiceFinderHub;
import io.appform.ranger.core.model.ServiceNodeSelector;
@@ -46,7 +46,7 @@ public abstract class AbstractRangerHttpHubClient httpClient;
@Builder.Default
- private final ServiceNodeSelector nodeSelector = new RandomServiceNodeSelector<>();
+ private final ServiceNodeSelector nodeSelector = new WeightedRandomServiceNodeSelector<>();
@Override
protected ServiceDataSource getDefaultDataSource() {
diff --git a/ranger-http-model/pom.xml b/ranger-http-model/pom.xml
index 091dc08c..436d9ae3 100644
--- a/ranger-http-model/pom.xml
+++ b/ranger-http-model/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0
diff --git a/ranger-http/pom.xml b/ranger-http/pom.xml
index 54a6eb2d..69243068 100644
--- a/ranger-http/pom.xml
+++ b/ranger-http/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0
diff --git a/ranger-hub-server-bundle/pom.xml b/ranger-hub-server-bundle/pom.xml
index 6ec8bbcd..a90ae07a 100644
--- a/ranger-hub-server-bundle/pom.xml
+++ b/ranger-hub-server-bundle/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
diff --git a/ranger-server-bundle/pom.xml b/ranger-server-bundle/pom.xml
index a50ddef8..0712ea58 100644
--- a/ranger-server-bundle/pom.xml
+++ b/ranger-server-bundle/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0
diff --git a/ranger-server-common/pom.xml b/ranger-server-common/pom.xml
index ceeefd82..b0c51bef 100644
--- a/ranger-server-common/pom.xml
+++ b/ranger-server-common/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0
diff --git a/ranger-server/pom.xml b/ranger-server/pom.xml
index d71666ab..7b4cf7f4 100644
--- a/ranger-server/pom.xml
+++ b/ranger-server/pom.xml
@@ -22,7 +22,7 @@
io.appform.ranger
ranger
- 1.1-RC5
+ 1.2-RC5
ranger-server
diff --git a/ranger-zk-client/pom.xml b/ranger-zk-client/pom.xml
index 907a8343..cd14b549 100644
--- a/ranger-zk-client/pom.xml
+++ b/ranger-zk-client/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0
diff --git a/ranger-zk-client/src/main/java/io/appform/ranger/client/zk/ShardedRangerZKHubClient.java b/ranger-zk-client/src/main/java/io/appform/ranger/client/zk/ShardedRangerZKHubClient.java
index 55af8445..7a8fd57c 100644
--- a/ranger-zk-client/src/main/java/io/appform/ranger/client/zk/ShardedRangerZKHubClient.java
+++ b/ranger-zk-client/src/main/java/io/appform/ranger/client/zk/ShardedRangerZKHubClient.java
@@ -15,7 +15,7 @@
*/
package io.appform.ranger.client.zk;
-import io.appform.ranger.core.finder.nodeselector.RandomServiceNodeSelector;
+import io.appform.ranger.core.finder.nodeselector.WeightedRandomServiceNodeSelector;
import io.appform.ranger.core.finder.serviceregistry.MapBasedServiceRegistry;
import io.appform.ranger.core.finder.shardselector.MatchingShardSelector;
import io.appform.ranger.core.finderhub.ServiceFinderFactory;
@@ -36,7 +36,7 @@ public class ShardedRangerZKHubClient
private final ShardSelector> shardSelector = new MatchingShardSelector<>();
@Builder.Default
- private final ServiceNodeSelector nodeSelector = new RandomServiceNodeSelector<>();
+ private final ServiceNodeSelector nodeSelector = new WeightedRandomServiceNodeSelector<>();
@Override
protected ServiceFinderFactory> getFinderFactory() {
diff --git a/ranger-zk-client/src/main/java/io/appform/ranger/client/zk/UnshardedRangerZKHubClient.java b/ranger-zk-client/src/main/java/io/appform/ranger/client/zk/UnshardedRangerZKHubClient.java
index 2b3eea83..59b8a6f9 100644
--- a/ranger-zk-client/src/main/java/io/appform/ranger/client/zk/UnshardedRangerZKHubClient.java
+++ b/ranger-zk-client/src/main/java/io/appform/ranger/client/zk/UnshardedRangerZKHubClient.java
@@ -15,7 +15,7 @@
*/
package io.appform.ranger.client.zk;
-import io.appform.ranger.core.finder.nodeselector.RandomServiceNodeSelector;
+import io.appform.ranger.core.finder.nodeselector.WeightedRandomServiceNodeSelector;
import io.appform.ranger.core.finder.serviceregistry.ListBasedServiceRegistry;
import io.appform.ranger.core.finder.shardselector.ListShardSelector;
import io.appform.ranger.core.finderhub.ServiceFinderFactory;
@@ -36,7 +36,7 @@ public class UnshardedRangerZKHubClient
private final ShardSelector> shardSelector = new ListShardSelector<>();
@Builder.Default
- private final ServiceNodeSelector nodeSelector = new RandomServiceNodeSelector<>();
+ private final ServiceNodeSelector nodeSelector = new WeightedRandomServiceNodeSelector<>();
@Override
protected ServiceFinderFactory> getFinderFactory() {
diff --git a/ranger-zookeeper/pom.xml b/ranger-zookeeper/pom.xml
index d1e9ad24..d8d01720 100644
--- a/ranger-zookeeper/pom.xml
+++ b/ranger-zookeeper/pom.xml
@@ -21,7 +21,7 @@
ranger
io.appform.ranger
- 1.1-RC5
+ 1.2-RC5
4.0.0