Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
thsc42 committed Dec 5, 2023
2 parents ee73cdf + e26bd7c commit d2a2a7a
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 47 deletions.
68 changes: 49 additions & 19 deletions src/main/java/net/sharksystem/hub/BasicHubConnectionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
* A streamlined facade meant to be used on service side of an ASAP application that makes use of hubs.
* This class assumes the proposed architecture: A connection handler (in most cases subclassed from ASAPPeer)
* is wrapped into an encounter manager.
*
* <p>
* Instances of that hub connection manager class are initiated with that encounter manager and an ASAPPeer instance.
*
* <p>
* It provides just a few methods to connect and disconnect hubs. Some optional behaviour is hidden.
*/
public abstract class BasicHubConnectionManager implements HubConnectionManager {
Expand All @@ -30,32 +30,33 @@ public abstract class BasicHubConnectionManager implements HubConnectionManager
* Hub manager can be asked to connect to or disconnect from hubs. We send a list of hubs which are to be
* connected. Connection establishment can take a while, though. It is a wish list on application side for a while.
* Connection establishment can fail - not any wish can be fulfilled.
*
* <p>
* We assume that this methode is called due to user interaction. Meaning: Intervals between two calls are long
* enough to establish a connection or fail in the attempt. Implication: We assume: hub internal list is always
* accurate. We can keep track of failed attempts. And we do.
*/
protected void syncLists() {
// avoid calls within milliseconds
long now = System.currentTimeMillis();
if(now - this.lastSync <= 100) return;
if (now - this.lastSync <= 100) return;
this.lastSync = now;

// ask for current list from hub
List<HubConnectorDescription> toBeRemoved = new ArrayList<>();
for(HubConnectorDescription wishedConnection : this.hcdList) {
for (HubConnectorDescription wishedConnection : this.hcdList) {
boolean found = false;
for(HubConnectorDescription runningConnection : this.hcdListHub) {
if(wishedConnection.isSame(runningConnection)) {
for (HubConnectorDescription runningConnection : this.hcdListHub) {
if (wishedConnection.isSame(runningConnection)) {
found = true;
break; // found - go ahead.
}
}
if(!found) toBeRemoved.add(wishedConnection);
// remove failed attempt from connected hubs list
if (!found) toBeRemoved.add(wishedConnection);
}

// remove and remember unfulfilled wishes
for(HubConnectorDescription failedConnection : toBeRemoved) {
for (HubConnectorDescription failedConnection : toBeRemoved) {
// 1st remove from wish list
this.hcdList.remove(failedConnection);

Expand All @@ -67,19 +68,37 @@ protected void syncLists() {
break;
}
}
if(recordedOldAttempt != null) this.failedConnectionAttempts.remove(recordedOldAttempt);
if (recordedOldAttempt != null) this.failedConnectionAttempts.remove(recordedOldAttempt);
this.failedConnectionAttempts.add(new HubConnectionManager.FailedConnectionAttempt() {
@Override
public HubConnectorDescription getHubConnectorDescription() { return failedConnection; }
public HubConnectorDescription getHubConnectorDescription() {
return failedConnection;
}

@Override
public long getTimeStamp() { return lastConnectionAttempt; }
public long getTimeStamp() {
return lastConnectionAttempt;
}
});
}

// remove attempts which where successful later on
List<FailedConnectionAttempt> connectedNow = new ArrayList<>();
for (HubConnectionManager.FailedConnectionAttempt failedAttempt : this.failedConnectionAttempts) {
for (HubConnectorDescription runningConnection : this.hcdListHub) {
if (failedAttempt.getHubConnectorDescription().isSame(runningConnection)) {
connectedNow.add(failedAttempt);
}
}
}
for (FailedConnectionAttempt failedAttempt : connectedNow) {
this.failedConnectionAttempts.remove(failedAttempt);
}
}

private HubConnectorDescription findSameInList(HubConnectorDescription hcd, List<HubConnectorDescription> hcdList) {
for(HubConnectorDescription hcdInList : hcdList) {
if(hcd.isSame(hcdInList)) {
for (HubConnectorDescription hcdInList : hcdList) {
if (hcd.isSame(hcdInList)) {
return hcdInList;
}
}
Expand All @@ -90,7 +109,7 @@ private HubConnectorDescription findSameInList(HubConnectorDescription hcd, List
public void connectHub(HubConnectorDescription hcd) throws SharkException, IOException {
this.lastConnectionAttempt = System.currentTimeMillis(); // new connection attempt
// already connected?
if(this.findSameInList(hcd, this.hcdList) != null) return; // yes, connected: nothing to do here
if (this.findSameInList(hcd, this.hcdList) != null) return; // yes, connected: nothing to do here
// else
this.hcdList.add(hcd);
}
Expand All @@ -100,10 +119,21 @@ public void connectHub(HubConnectorDescription hcd) throws SharkException, IOExc
public void disconnectHub(HubConnectorDescription hcd) throws SharkException, IOException {
// *not* in there?
HubConnectorDescription disconnectHcd = this.findSameInList(hcd, this.hcdList);
if(disconnectHcd == null) return; // not connected - nothing to do here
// else
this.hcdList.remove(disconnectHcd);
// sync hub connections
if (disconnectHcd != null) {
this.hcdList.remove(disconnectHcd);
} else {
// remove hcd from failed attempts list
FailedConnectionAttempt attemptToRemove = null;
for (FailedConnectionAttempt failedAttempt : this.failedConnectionAttempts) {
if(failedAttempt.getHubConnectorDescription().isSame(hcd)){
attemptToRemove = failedAttempt;
break;
}
}
if (attemptToRemove != null) this.failedConnectionAttempts.remove(attemptToRemove);
}


}

@Override
Expand Down
28 changes: 26 additions & 2 deletions src/test/java/net/sharksystem/hub/HubConnectionManagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,38 @@ public void disconnectHubEdgeFailedConnectionAttempt() throws IOException, Shark
assertEquals(1, hubConnectionManager.getFailedConnectionAttempts().size());


hubConnectionManager.disconnectHub(localHostHubDescription);
hubConnectionManager.disconnectHub(hubDescriptionWrongPort);
// give it some time for disconnecting
Thread.sleep(1000);
// connected hub list should contain one item
assertEquals(0, hubConnectionManager.getConnectedHubs().size());
// still one element left after disconnecting
// TODO clarify whether this is a bug
assertEquals(0, hubConnectionManager.getFailedConnectionAttempts().size());
}

@Test
public void connectHubEdgeSuccessfulAttemptAfterFailedAttempt() throws IOException, SharkException, InterruptedException {
HubConnectorDescription hubDescriptionSecondHub = new TCPHubConnectorDescriptionImpl("localhost",
hubPort + 1, multiChannel);
hubConnectionManager.connectHub(hubDescriptionSecondHub);
// give it some time for connection attempt
Thread.sleep(1000);

// first attempt should fail, because hub wasn't started yet
assertEquals(0, hubConnectionManager.getConnectedHubs().size());
assertEquals(1, hubConnectionManager.getFailedConnectionAttempts().size());

ASAPTCPHub asapHub2 = ASAPTCPHub.startTCPHubThread(hubPort+1, multiChannel, MAX_IDLE_IN_SECONDS);
hubConnectionManager.connectHub(hubDescriptionSecondHub);

// give it some time for connection establishment
Thread.sleep(1000);
// connection should be established now
assertEquals(1, hubConnectionManager.getConnectedHubs().size());
// failed attempt from first try should be removed
assertEquals(0, hubConnectionManager.getFailedConnectionAttempts().size());

asapHub2.kill();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public class KnownBugsHubConnectionManagerTest {
@Before
public void setUp() throws Exception {
hubPort = TestHelper.getPortNumber();
HubConnectorDescription localHostHubDescription = new TCPHubConnectorDescriptionImpl("localhost", hubPort, multiChannel);
ASAPPeerFS asapPeer = new ASAPTestPeerFS(ALICE_ID, Collections.singletonList(FORMAT));
hubConnectionManager = new HubConnectionManagerImpl(new ASAPEncounterManagerImpl(asapPeer), asapPeer);
asapHub = ASAPTCPHub.startTCPHubThread(hubPort, multiChannel, MAX_IDLE_IN_SECONDS);
Expand Down Expand Up @@ -60,29 +59,4 @@ public void connectHubEdgeTwoAttempts() throws IOException, SharkException, Inte
asapHub2.kill();
}

@Test
public void connectHubEdgeSuccessfulAttemptAfterFailedAttempt() throws IOException, SharkException, InterruptedException {
HubConnectorDescription hubDescriptionSecondHub = new TCPHubConnectorDescriptionImpl("localhost",
hubPort + 1, multiChannel);
hubConnectionManager.connectHub(hubDescriptionSecondHub);
// give it some time for connection attempt
Thread.sleep(1000);

// first attempt should fail, because hub wasn't started yet
assertEquals(0, hubConnectionManager.getConnectedHubs().size());
assertEquals(1, hubConnectionManager.getFailedConnectionAttempts().size());

ASAPTCPHub asapHub2 = ASAPTCPHub.startTCPHubThread(hubPort+1, multiChannel, MAX_IDLE_IN_SECONDS);
hubConnectionManager.connectHub(hubDescriptionSecondHub);

// give it some time for connection establishment
Thread.sleep(1000);
// connection should be established now
assertEquals(1, hubConnectionManager.getConnectedHubs().size());
// failed attempt from first try should be removed
assertEquals(0, hubConnectionManager.getFailedConnectionAttempts().size());

asapHub2.kill();
}

}

0 comments on commit d2a2a7a

Please sign in to comment.