diff options
5 files changed, 66 insertions, 1 deletions
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/CleanOldGossipsMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/CleanOldGossipsMessage.java new file mode 100644 index 0000000..6c3cb7e --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/CleanOldGossipsMessage.java @@ -0,0 +1,16 @@ +package pl.edu.mimuw.cloudatlas.agent.messages; + +import pl.edu.mimuw.cloudatlas.model.ValueTime; + +public class CleanOldGossipsMessage extends GossipGirlMessage { + private ValueTime ageThreshold; + + public CleanOldGossipsMessage(String messageId, long timestamp, ValueTime ageThreshold) { + super(messageId, timestamp, Type.CLEAN); + this.ageThreshold = ageThreshold; + } + + public ValueTime getAgeThreshold() { + return ageThreshold; + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GossipGirlMessage.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GossipGirlMessage.java index 03525bb..6255e3b 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GossipGirlMessage.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/messages/GossipGirlMessage.java @@ -9,7 +9,8 @@ public abstract class GossipGirlMessage extends AgentMessage { HEJKA, INITIATE, NO_CO_TAM, - QUERY + QUERY, + CLEAN } private Type type; diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirl.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirl.java index dd8f0b7..ec34c7f 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirl.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirl.java @@ -2,10 +2,12 @@ package pl.edu.mimuw.cloudatlas.agent.modules; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import pl.edu.mimuw.cloudatlas.agent.messages.AttributesMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.CleanOldGossipsMessage; import pl.edu.mimuw.cloudatlas.agent.messages.GetStateMessage; import pl.edu.mimuw.cloudatlas.agent.messages.GossipGirlMessage; import pl.edu.mimuw.cloudatlas.agent.messages.HejkaMessage; @@ -51,6 +53,9 @@ public class GossipGirl extends Module { case QUERY: handleQuery((QueryMessage) message); break; + case CLEAN: + cleanOldGossips((CleanOldGossipsMessage) message); + break; default: throw new InvalidMessageType("This type of message cannot be handled by GossipGirl"); } @@ -95,6 +100,7 @@ public class GossipGirl extends Module { private void setState(StateMessage message) throws InterruptedException { GossipGirlState state = gossipStates.get(message.getRequestId()); if (state != null) { + state.setLastAction(); state.setState(message.getZMI(), message.getQueries()); if (state.state == GossipGirlState.State.SEND_HEJKA) { HejkaMessage hejka = new HejkaMessage( @@ -132,6 +138,7 @@ public class GossipGirl extends Module { private void handleNoCoTam(NoCoTamMessage message) throws InterruptedException { GossipGirlState state = gossipStates.get(message.getReceiverGossipId()); if (state != null) { + state.setLastAction(); state.handleNoCoTam(message); sendInfo(state); } else { @@ -157,6 +164,7 @@ public class GossipGirl extends Module { private void handleAttributes(AttributesMessage message) throws InterruptedException { GossipGirlState state = gossipStates.get(message.getReceiverGossipId()); if (state != null) { + state.setLastAction(); state.gotAttributes(message); if (state.state == GossipGirlState.State.SEND_INFO) { sendInfo(state); @@ -174,6 +182,7 @@ public class GossipGirl extends Module { private void handleQuery(QueryMessage message) throws InterruptedException { GossipGirlState state = gossipStates.get(message.getReceiverGossipId()); if (state != null) { + state.setLastAction(); state.gotQuery(message.getName()); Map<Attribute, Entry<ValueQuery, ValueTime>> queries = new HashMap(); queries.put( @@ -189,4 +198,14 @@ public class GossipGirl extends Module { System.out.println("ERROR: GossipGirl got query for a nonexistent gossip"); } } + + private void cleanOldGossips(CleanOldGossipsMessage message) { + Iterator<Entry<Long, GossipGirlState>> iterator = gossipStates.entrySet().iterator(); + while (iterator.hasNext()) { + GossipGirlState state = iterator.next().getValue(); + if (state.lastAction.isLowerThan(message.getAgeThreshold()).getValue()) { + iterator.remove(); + } + } + } } diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java index eafbcca..70d57d9 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java @@ -36,6 +36,7 @@ public class GossipGirlState { FINISHED, ERROR } + public ValueTime lastAction; public PathName ourPath; public ValueContact theirContact; public long gossipId; @@ -64,6 +65,11 @@ public class GossipGirlState { } else { state = State.APPLY_HEJKA; } + this.lastAction = ValueUtils.currentTime(); + } + + public void setLastAction() { + lastAction = ValueUtils.currentTime(); } public void setState(ZMI hierarchy, Map<Attribute, Entry<ValueQuery, ValueTime>> queries) { diff --git a/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlTest.java b/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlTest.java index 5fac535..2d7b15f 100644 --- a/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlTest.java +++ b/src/test/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlTest.java @@ -16,6 +16,7 @@ import java.util.Set; import pl.edu.mimuw.cloudatlas.agent.MockExecutor; import pl.edu.mimuw.cloudatlas.agent.messages.AgentMessage; import pl.edu.mimuw.cloudatlas.agent.messages.AttributesMessage; +import pl.edu.mimuw.cloudatlas.agent.messages.CleanOldGossipsMessage; import pl.edu.mimuw.cloudatlas.agent.messages.HejkaMessage; import pl.edu.mimuw.cloudatlas.agent.messages.GetStateMessage; import pl.edu.mimuw.cloudatlas.agent.messages.GossipGirlMessage; @@ -410,6 +411,28 @@ public class GossipGirlTest { gossipGirl.handleTyped(queryMessage2); } + @Test + public void cleanupOldGossips() throws Exception { + gossipGirl.handleTyped(hejkaMessage); + executor.messagesToPass.take(); + gossipGirl.handleTyped(stateMessage); + executor.messagesToPass.take(); + + gossipGirl.handleTyped(attributesMessage1); + executor.messagesToPass.take(); + executor.messagesToPass.take(); + executor.messagesToPass.take(); + executor.messagesToPass.take(); + executor.messagesToPass.take(); + executor.messagesToPass.take(); + + CleanOldGossipsMessage message = new CleanOldGossipsMessage("", 0, TestUtil.addToTime(ValueUtils.currentTime(), 10)); + gossipGirl.handleTyped(message); + gossipGirl.handleTyped(attributesMessage2); + + assertEquals(0, executor.messagesToPass.size()); + } + private void assertQueryMessage(AgentMessage message, String recipientPath, String name, String query) throws Exception { assertUDUPMessage( message, |