Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
estheme committed Dec 5, 2013
2 parents aa12213 + be0554b commit caabab9
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 25 deletions.
155 changes: 136 additions & 19 deletions src/chord/RMINode.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
*/
public class RMINode implements RMINodeServer, RMINodeState {

private static final int FIX_FINGER_INTERVAL = 1000;
private final int networkRetries;
private final int hashLength;
private final long nodeKey;
private FingerTable fingerTable;
Expand All @@ -30,7 +32,7 @@ public void run() {
while (!isInterrupted()) {
try {
synchronized (this) {
wait(1000);
wait(FIX_FINGER_INTERVAL);
}
} catch (InterruptedException e) {
break;
Expand All @@ -44,28 +46,42 @@ public void run() {
public RMINode(final int hashLength, final long nodeKey) {
this.hashLength = hashLength;
this.nodeKey = nodeKey;
networkRetries = hashLength + 1;
fingerTable = new FingerTable(this.hashLength, this.nodeKey);

backgroundThread.start();
}

/**
* Check if this node has left and throw an exception if it has.
*
* @throws RemoteException
*/
private void checkHasNodeLeft() throws RemoteException {
if (hasNodeLeft)
throw new RemoteException();
}

/**
* {@inheritDoc}
*/
@Override
public int getHashLength() throws RemoteException {
checkHasNodeLeft();
return hashLength;
}

/**
* {@inheritDoc}
*/
@Override
public long getNodeKey() throws RemoteException {
checkHasNodeLeft();
return nodeKey;
}

/**
* {@inheritDoc}
*/
@Override
public NodeState getState() throws RemoteException {
checkHasNodeLeft();
Expand All @@ -90,6 +106,9 @@ public NodeState getState() throws RemoteException {
return new NodeState(getNodeKey(), predecessorNodeKey, fingers, 0);
}

/**
* {@inheritDoc}
*/
@Override
public void join(RMINodeServer fromNetwork) throws RemoteException {
checkHasNodeLeft();
Expand All @@ -102,53 +121,121 @@ public void join(RMINodeServer fromNetwork) throws RemoteException {
}
}

/**
* {@inheritDoc}
*/
@Override
public void leave() throws RemoteException {
hasNodeLeft = true;
forwardDataToSuccessor();
}

/**
* {@inheritDoc}
*/
@Override
public Serializable get(long key) throws RemoteException {
checkHasNodeLeft();

// TODO Auto-generated method stub
for (int i = 0; i < networkRetries; i++) {
checkHasNodeLeft();
try {
RMINodeServer server = findSuccessor(key);
if (nodeKey == server.getNodeKey())
return nodeStorage.get(key);
else
return server.get(key);
} catch (NullPointerException | RemoteException e ) {
// some node somewhere is dead... wait a while for our fingers to
// correct then try again
try {
Thread.sleep(FIX_FINGER_INTERVAL);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
// tried a bunch of times and failed, throw in the towel.
return null;
}

/**
* {@inheritDoc}
*/
@Override
public Serializable get(String key) throws RemoteException {
checkHasNodeLeft();

// TODO Auto-generated method stub
return null;
return get(new KeyHash<String>(key, hashLength).getHash());
}

/**
* {@inheritDoc}
*/
@Override
public void put(long key, Serializable value) throws RemoteException {

// TODO Auto-generated method stub

for (int i = 0; i < networkRetries; i++) {
checkHasNodeLeft();
try {
RMINodeServer server = findSuccessor(key);
if (nodeKey == server.getNodeKey())
nodeStorage.put(key, value);
else
server.put(key, value);
} catch (NullPointerException | RemoteException e ) {
// some node somewhere is dead... wait a while for our fingers to
// correct then try again
try {
Thread.sleep(FIX_FINGER_INTERVAL);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
// tried a bunch of times and failed, throw in the towel.
}

/**
* {@inheritDoc}
*/
@Override
public void put(String key, Serializable value) throws RemoteException {
// TODO Auto-generated method stub

put(new KeyHash<String>(key, hashLength).getHash(), value);
}

/**
* {@inheritDoc}
*/
@Override
public void delete(long key) throws RemoteException {
// TODO Auto-generated method stub

for (int i = 0; i < networkRetries; i++) {
checkHasNodeLeft();
try {
RMINodeServer server = findSuccessor(key);
if (nodeKey == server.getNodeKey())
nodeStorage.remove(key);
else
server.delete(key);
} catch (NullPointerException | RemoteException e ) {
// some node somewhere is dead... wait a while for our fingers to
// correct then try again
try {
Thread.sleep(FIX_FINGER_INTERVAL);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
// tried a bunch of times and failed, throw in the towel.
}

/**
* {@inheritDoc}
*/
@Override
public void delete(String key) throws RemoteException {
// TODO Auto-generated method stub

delete(new KeyHash<String>(key, hashLength).getHash());
}

/**
* {@inheritDoc}
*/
@Override
public RMINodeServer findSuccessor(long key) throws RemoteException {
checkHasNodeLeft();
Expand Down Expand Up @@ -176,13 +263,18 @@ public RMINodeServer findSuccessor(long key) throws RemoteException {
return this;
}

/**
* {@inheritDoc}
*/
@Override
public RMINodeServer getPredecessor() throws RemoteException {
checkHasNodeLeft();

return predecessor;
}

/**
* {@inheritDoc}
*/
@Override
public void checkPredecessor(RMINodeServer potentialPredecessor) throws RemoteException {
checkHasNodeLeft();
Expand Down Expand Up @@ -256,6 +348,9 @@ public void forwardDataToSuccessor() {
}
}

/**
* {@inheritDoc}
*/
@Override
public void nodeLeaving(long leavingNodeKey) throws RemoteException {
checkHasNodeLeft();
Expand Down Expand Up @@ -310,4 +405,26 @@ private void stabilize() {
fingerTable.getSuccessor().setNode(this);
}
}

/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object other) {
RMINode otherNode;
if (other instanceof RMINode) {
otherNode = (RMINode) other;
} else {
return false;
}
try {
if (this.getNodeKey() == otherNode.getNodeKey()) {
return true;
} else {
return false;
}
} catch (RemoteException e) {
return false;
}
}
}
2 changes: 2 additions & 0 deletions src/team-executive-summary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ We corrected some problems that we had in the previous assignment with sharing t

Dan discovered a bug from the previous homework with the way that the integer range for the size of the network was being calculated. Our previous tests had not uncovered the problem, but additional testing in this homework did. We were able to incorporate the fix into the new code and resolve the issue.

Later, we discovered some other bugs that cropped up during the process of a node leaving the network. RMI appeared to be consuming all network connections when a node left the network, causing crashes. We traced the bug down to a couple of methods but were unable to determine exactly what was causing the issue. Eventually we revisited (and rewrote) a significant chunk of the code and were able to resolve a number of the problems with the network stability.

Team Report

We split up the work this time around with Dan working on nodes joining and exiting the network; Sven working on updating the logging functionality and updating the design doc based on our changes; and Jesse working on storage and retrieval of data in the network and drafting the executive summary. We worked remotely over the holiday and kept in communication via email. We also tracked project task updates using the Trello app. We ended up all being scattered out of town for the Thanksgiving holiday which made some of the communication difficult, but we managed reasonably well. Jesse and Sven both dealt with some illness as well.
12 changes: 6 additions & 6 deletions src/test/ChordStorageTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public void testGetAndPut() throws AccessException, RemoteException, NotBoundExc
String key = "testKey";
String value = "testValue";
client.put(key, value);
String getValue = (String) client.get(key);
assertEquals(value, getValue);
String returnValue = (String) client.get(key);
assertEquals(value, returnValue);
}

@Test
Expand All @@ -50,8 +50,8 @@ public void testGetAndPutWithDifferentClients() throws AccessException, RemoteEx
putClient.put(key, value);
RMINodeClient getClient = (RMINodeClient) registry.lookup("node1");
getClient.get(key);
String getValue = (String) putClient.get(key);
assertEquals(value, getValue);
String returnValue = (String) putClient.get(key);
assertEquals(value, returnValue);
}

@Test
Expand All @@ -62,8 +62,8 @@ public void testDelete() throws RemoteException, NotBoundException {
client.put(key, value);
assertEquals(value, client.get(key));
client.delete(key);
String getValue = (String) client.get(key);
assertEquals(null, getValue);
String nullValue = (String) client.get(key);
assertEquals(null, nullValue);
}

@Test
Expand Down

0 comments on commit caabab9

Please sign in to comment.