Introducing the FullNode class, which keeps track of the delay to each full node it represents
This commit is contained in:
parent
56fb257eb2
commit
83ce2de14d
3 changed files with 143 additions and 0 deletions
|
@ -0,0 +1,63 @@
|
||||||
|
package cy.agorise.graphenej.network;
|
||||||
|
import cy.agorise.graphenej.stats.ExponentialMovingAverage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that represents a full node and is used to keep track of its round-trip time measured in milliseconds.
|
||||||
|
*/
|
||||||
|
public class FullNode implements Comparable {
|
||||||
|
private String mUrl;
|
||||||
|
private ExponentialMovingAverage latency;
|
||||||
|
|
||||||
|
private FullNode(){}
|
||||||
|
|
||||||
|
public FullNode(String url){
|
||||||
|
latency = new ExponentialMovingAverage(ExponentialMovingAverage.DEFAULT_ALPHA);
|
||||||
|
this.mUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Full node URL getter
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getUrl() {
|
||||||
|
return mUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Full node URL setter
|
||||||
|
* @param mUrl
|
||||||
|
*/
|
||||||
|
public void setUrl(String mUrl) {
|
||||||
|
this.mUrl = mUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return The exponential moving average object instance
|
||||||
|
*/
|
||||||
|
public ExponentialMovingAverage getLatencyAverage(){
|
||||||
|
return latency;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return The latest latency average value
|
||||||
|
*/
|
||||||
|
public double getLatencyValue() {
|
||||||
|
return latency.getAverage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that updates the latency average with a new value.
|
||||||
|
* @param latency Most recent latency sample to be added to the exponential average
|
||||||
|
*/
|
||||||
|
public void addLatencyValue(double latency) {
|
||||||
|
this.latency.updateValue(latency);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Object o) {
|
||||||
|
FullNode node = (FullNode) o;
|
||||||
|
return (int) Math.ceil(latency.getAverage() - node.getLatencyValue());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package cy.agorise.graphenej.stats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to compute the Exponential Moving Average of a sequence of values.
|
||||||
|
* For more details see <a href="https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average">here</a>.
|
||||||
|
*/
|
||||||
|
public class ExponentialMovingAverage {
|
||||||
|
public static final double DEFAULT_ALPHA = 0.5;
|
||||||
|
private double alpha;
|
||||||
|
private Double accumulatedValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor, which takes only the alpha parameter as an argument.
|
||||||
|
*
|
||||||
|
* @param alpha The coefficient alpha represents the degree of weighting decrease, a constant
|
||||||
|
* smoothing factor between 0 and 1. A higher alpha discounts older observations faster.
|
||||||
|
*/
|
||||||
|
public ExponentialMovingAverage(double alpha) {
|
||||||
|
this.alpha = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that updates the average with a new sample
|
||||||
|
* @param value New value
|
||||||
|
* @return The updated average value
|
||||||
|
*/
|
||||||
|
public double updateValue(double value) {
|
||||||
|
if (accumulatedValue == null) {
|
||||||
|
accumulatedValue = value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
double newValue = accumulatedValue + alpha * (value - accumulatedValue);
|
||||||
|
accumulatedValue = newValue;
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return Returns the current average value
|
||||||
|
*/
|
||||||
|
public double getAverage(){
|
||||||
|
return accumulatedValue == null ? 0 : accumulatedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlpha(double alpha){
|
||||||
|
this.alpha = alpha;
|
||||||
|
this.accumulatedValue = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package cy.agorise.graphenej.network;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class FullNodeTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFullNodeComparable(){
|
||||||
|
FullNode nodeA = new FullNode("wss://dummy");
|
||||||
|
FullNode nodeB = new FullNode("wss://dummy");
|
||||||
|
FullNode nodeC = new FullNode("wss://dummy");
|
||||||
|
nodeA.addLatencyValue(100);
|
||||||
|
nodeB.addLatencyValue(200);
|
||||||
|
nodeC.addLatencyValue(100);
|
||||||
|
Assert.assertTrue("Makes sure the node nodeA.compareTo(nodeB) returns a negative value", nodeA.compareTo(nodeB) < 0);
|
||||||
|
Assert.assertTrue("Makes sure nodeA.compareTo(nodeB) returns zero", nodeA.compareTo(nodeC) == 0);
|
||||||
|
Assert.assertTrue("Makes sure nodeB.compareTo(nodeA) returns a positive value", nodeB.compareTo(nodeA) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFullNodeAverageLatency(){
|
||||||
|
FullNode fullNode = new FullNode("wss://dummy");
|
||||||
|
fullNode.getLatencyAverage().setAlpha(0.5);
|
||||||
|
fullNode.addLatencyValue(100);
|
||||||
|
Assert.assertEquals(100.0, fullNode.getLatencyValue());
|
||||||
|
fullNode.addLatencyValue(50);
|
||||||
|
Assert.assertEquals(75.0, fullNode.getLatencyValue());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue