- Added a method to remove nodes from LatencyNodeProvider and implemented a HashSet to keep track of such removed nodes. The reason is that calls to this class are asynchronous and only removing a node from the mFullNodeHeap was not enough to guarantee that it was not going to be added again.

- Added a isRemoved variable to FullNode class, so that the object can carry itself the removal status information and be able to use the same publish subject to broadcast the status of the FullNode.
- Added a method to remove nodes from NodeLatencyVerifier, removed such nodes from pending node latency measurements map 'nodeURLMap' and publish/broadcast the FullNode information with isRemoved=true so that components listening can act accordingly.
- Make proper changes to sample app's RemoteNodeActivity so that it removes 'removed' nodes from the list.
This commit is contained in:
Severiano Jaramillo 2018-11-08 15:14:01 -06:00
parent 21311ea5a3
commit b6aab142b6
6 changed files with 74 additions and 10 deletions

View file

@ -703,9 +703,11 @@ public class NetworkService extends Service {
mApiIds.clear(); mApiIds.clear();
if (removeSelectedNode) { if (removeSelectedNode) {
// TODO change method to actually remove the node from the list // Remove node from node provider so that it is not returned for following connections
mSelectedNode.addLatencyValue(Long.MAX_VALUE); nodeProvider.removeNode(mSelectedNode);
nodeProvider.updateNode(mSelectedNode);
// Remove node from nodeLatencyVerifier, so that it publishes its removal
nodeLatencyVerifier.removeNode(mSelectedNode);
} else { } else {
// Adding a very high latency value to this node in order to prevent // Adding a very high latency value to this node in order to prevent
// us from getting it again // us from getting it again

View file

@ -10,6 +10,7 @@ public class FullNode implements Comparable {
private String mUrl; private String mUrl;
private ExponentialMovingAverage mLatency; private ExponentialMovingAverage mLatency;
private boolean isConnected; private boolean isConnected;
private boolean isRemoved;
private FullNode(){} private FullNode(){}
@ -77,6 +78,14 @@ public class FullNode implements Comparable {
isConnected = connected; isConnected = connected;
} }
public boolean isRemoved() {
return isRemoved;
}
public void setRemoved(boolean removed) {
isRemoved = removed;
}
/** /**
* Method that updates the mLatency average with a new value. * Method that updates the mLatency average with a new value.
* @param latency Most recent mLatency sample to be added to the exponential average * @param latency Most recent mLatency sample to be added to the exponential average

View file

@ -2,14 +2,18 @@ package cy.agorise.graphenej.network;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.PriorityQueue; import java.util.PriorityQueue;
public class LatencyNodeProvider implements NodeProvider { public class LatencyNodeProvider implements NodeProvider {
private HashSet<String> mRemovedNodeURLs;
private PriorityQueue<FullNode> mFullNodeHeap; private PriorityQueue<FullNode> mFullNodeHeap;
public LatencyNodeProvider(){ public LatencyNodeProvider(){
mFullNodeHeap = new PriorityQueue<>(); mFullNodeHeap = new PriorityQueue<>();
mRemovedNodeURLs = new HashSet<>();
} }
@Override @Override
@ -20,12 +24,16 @@ public class LatencyNodeProvider implements NodeProvider {
@Override @Override
public void addNode(FullNode fullNode) { public void addNode(FullNode fullNode) {
mFullNodeHeap.add(fullNode); mFullNodeHeap.add(fullNode);
mRemovedNodeURLs.remove(fullNode.getUrl());
} }
@Override @Override
public boolean updateNode(FullNode fullNode) { public boolean updateNode(FullNode fullNode) {
mFullNodeHeap.remove(fullNode); if (!mRemovedNodeURLs.contains(fullNode.getUrl())) {
return mFullNodeHeap.offer(fullNode); mFullNodeHeap.remove(fullNode);
return mFullNodeHeap.offer(fullNode);
}
return false;
} }
/** /**
@ -36,7 +44,7 @@ public class LatencyNodeProvider implements NodeProvider {
* @return True if the node priority was updated successfully * @return True if the node priority was updated successfully
*/ */
public boolean updateNode(FullNode fullNode, int latency){ public boolean updateNode(FullNode fullNode, int latency){
if(mFullNodeHeap.remove(fullNode)){ if(!mRemovedNodeURLs.contains(fullNode.getUrl()) && mFullNodeHeap.remove(fullNode)){
fullNode.addLatencyValue(latency); fullNode.addLatencyValue(latency);
return mFullNodeHeap.add(fullNode); return mFullNodeHeap.add(fullNode);
}else{ }else{
@ -44,6 +52,13 @@ public class LatencyNodeProvider implements NodeProvider {
} }
} }
@Override
public void removeNode(FullNode fullNode) {
if (mFullNodeHeap.remove(fullNode)) {
mRemovedNodeURLs.add(fullNode.getUrl());
}
}
@Override @Override
public List<FullNode> getSortedNodes() { public List<FullNode> getSortedNodes() {
FullNode[] nodeArray = mFullNodeHeap.toArray(new FullNode[mFullNodeHeap.size()]); FullNode[] nodeArray = mFullNodeHeap.toArray(new FullNode[mFullNodeHeap.size()]);

View file

@ -183,4 +183,24 @@ public class NodeLatencyVerifier {
} }
} }
} }
/**
* Removes the given node from the nodes list
* @param fullNode The node to remove
*/
public void removeNode(FullNode fullNode){
for(FullNode node : mNodeList){
if(node.equals(fullNode)){
mNodeList.remove(node);
String normalURL = node.getUrl().replace("wss://", "https://");
HttpUrl key = HttpUrl.parse(normalURL);
nodeURLMap.remove(key);
node.setRemoved(true);
subject.onNext(node);
break;
}
}
}
} }

View file

@ -26,13 +26,19 @@ public interface NodeProvider {
/** /**
* Updates the rating of a specific node that is already in the NodeProvider * Updates the rating of a specific node that is already in the NodeProvider
* @param fullNode * @param fullNode The node tu update
*/ */
boolean updateNode(FullNode fullNode); boolean updateNode(FullNode fullNode);
/**
* Removes the given node from the nodes list
* @param fullNode The node to remove
*/
void removeNode(FullNode fullNode);
/** /**
* Returns an ordered list of {@link FullNode} instances. * Returns an ordered list of {@link FullNode} instances.
* @return * @return The sorted list of nodes.
*/ */
List<FullNode> getSortedNodes(); List<FullNode> getSortedNodes();
} }

View file

@ -32,6 +32,7 @@ import java.util.Locale;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick;
import cy.agorise.graphenej.api.android.NetworkService; import cy.agorise.graphenej.api.android.NetworkService;
import cy.agorise.graphenej.network.FullNode; import cy.agorise.graphenej.network.FullNode;
import io.reactivex.Observer; import io.reactivex.Observer;
@ -67,6 +68,11 @@ public class RemoveNodeActivity extends AppCompatActivity implements ServiceConn
rvNodes.setAdapter(nodesAdapter); rvNodes.setAdapter(nodesAdapter);
} }
@OnClick(R.id.btnRemoveCurrentNode)
public void removeCurrentNode() {
mNetworkService.removeCurrentNodeAndReconnect();
}
@Override @Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) { public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
// We've bound to LocalService, cast the IBinder and get LocalService instance // We've bound to LocalService, cast the IBinder and get LocalService instance
@ -86,7 +92,7 @@ public class RemoveNodeActivity extends AppCompatActivity implements ServiceConn
@Override @Override
public void onServiceDisconnected(ComponentName componentName) { public void onServiceDisconnected(ComponentName componentName) {
mNetworkService = null;
} }
/** /**
@ -98,7 +104,10 @@ public class RemoveNodeActivity extends AppCompatActivity implements ServiceConn
@Override @Override
public void onNext(FullNode fullNode) { public void onNext(FullNode fullNode) {
nodesAdapter.add(fullNode); if (!fullNode.isRemoved())
nodesAdapter.add(fullNode);
else
nodesAdapter.remove(fullNode);
} }
@Override @Override
@ -265,6 +274,9 @@ public class RemoveNodeActivity extends AppCompatActivity implements ServiceConn
mSortedList.addAll(fullNodes); mSortedList.addAll(fullNodes);
} }
public void remove(FullNode fullNode) {
mSortedList.remove(fullNode);
}
@Override @Override
public int getItemCount() { public int getItemCount() {