Introducing the NodeProvider interface and its implementation LatencyNodeProvider

This commit is contained in:
Nelson R. Perez 2018-09-18 11:15:07 -05:00
parent 8c89c93935
commit 25222e5ea9
3 changed files with 156 additions and 0 deletions

View file

@ -0,0 +1,55 @@
package cy.agorise.graphenej.network;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
public class LatencyNodeProvider implements NodeProvider {
private PriorityQueue<FullNode> mFullNodeHeap;
public LatencyNodeProvider(){
mFullNodeHeap = new PriorityQueue<>();
}
@Override
public FullNode getBestNode() {
return mFullNodeHeap.peek();
}
@Override
public void addNode(FullNode fullNode) {
mFullNodeHeap.add(fullNode);
}
@Override
public boolean updateNode(FullNode fullNode) {
if(mFullNodeHeap.remove(fullNode)){
return mFullNodeHeap.offer(fullNode);
}else{
return false;
}
}
/**
* Updates an existing node with the new latency value.
*
* @param fullNode Existing full node instance
* @param latency New latency measurement
* @return True if the node priority was updated successfully
*/
public boolean updateNode(FullNode fullNode, int latency){
if(mFullNodeHeap.remove(fullNode)){
fullNode.addLatencyValue(latency);
return mFullNodeHeap.add(fullNode);
}else{
return false;
}
}
@Override
public List<FullNode> getSortedNodes() {
FullNode[] nodeArray = mFullNodeHeap.toArray(new FullNode[mFullNodeHeap.size()]);
Arrays.sort(nodeArray);
return Arrays.asList(nodeArray);
}
}

View file

@ -0,0 +1,38 @@
package cy.agorise.graphenej.network;
import java.util.List;
/**
* Interface used to describe the high level characteristics of a class that will
* hold and manage a list of {@link FullNode} instances.
*
* The idea is that the class implementing this interface should provide node instances
* and thus URLs for the {@link cy.agorise.graphenej.api.android.NetworkService} with
* different sorting heuristics.
*/
public interface NodeProvider {
/**
* Returns the node with the best characteristics.
* @return A FullNode instance
*/
FullNode getBestNode();
/**
* Adds a new node to the queue
* @param fullNode {@link FullNode} instance to add.
*/
void addNode(FullNode fullNode);
/**
* Updates the rating of a specific node that is already in the NodeProvider
* @param fullNode
*/
boolean updateNode(FullNode fullNode);
/**
* Returns an ordered list of {@link FullNode} instances.
* @return
*/
List<FullNode> getSortedNodes();
}

View file

@ -0,0 +1,63 @@
package cy.agorise.graphenej.network;
import junit.framework.Assert;
import org.junit.Test;
import java.util.List;
public class LatencyNodeProviderTest {
private FullNode nodeA, nodeB, nodeC;
private LatencyNodeProvider latencyNodeProvider;
private void setupTestNodes(){
// Creating 3 nodes with different latencies
nodeA = new FullNode("wss://nodeA");
nodeB = new FullNode("wss://nodeB");
nodeC = new FullNode("wss://nodeC");
// Adding latencies measurements
nodeA.addLatencyValue(100);
nodeB.addLatencyValue(50);
nodeC.addLatencyValue(20);
// Creating a node provider and adding the nodes created previously
latencyNodeProvider = new LatencyNodeProvider();
latencyNodeProvider.addNode(nodeC);
latencyNodeProvider.addNode(nodeA);
latencyNodeProvider.addNode(nodeB);
}
@Test
public void testSorting(){
setupTestNodes();
// Confirming that the best node is nodeC
FullNode bestNode = latencyNodeProvider.getBestNode();
System.out.println("Best node latency: "+bestNode.getLatencyValue());
Assert.assertSame("Check that the best node is nodeC", nodeC, bestNode);
// Improving nodeA score by feeding it with new better latency measurements
latencyNodeProvider.updateNode(nodeA, 10);
latencyNodeProvider.updateNode(nodeA, 10);
latencyNodeProvider.updateNode(nodeA, 10);
latencyNodeProvider.updateNode(nodeA, 10);
// Updating the nodeA position in the provider
latencyNodeProvider.updateNode(nodeA);
bestNode = latencyNodeProvider.getBestNode();
System.out.println("Best node latency after update: "+bestNode.getLatencyValue());
Assert.assertSame("Check that the best node now is the nodeA", nodeA, bestNode);
}
@Test
public void testSortedList(){
setupTestNodes();
// Confirming that the getSortedNodes gives us a sorted list of nodes in increasing latency order
List<FullNode> fullNodeList = latencyNodeProvider.getSortedNodes();
Assert.assertSame(nodeC, fullNodeList.get(0));
Assert.assertSame(nodeB, fullNodeList.get(1));
Assert.assertSame(nodeA, fullNodeList.get(2));
}
}