Ayaka Koshibe

add check for duplicate MastershipEvents to DeviceManager

Change-Id: I2753366b29ef32fa77ebcefff4b2202f1afe0006
...@@ -29,6 +29,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -29,6 +29,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
29 import org.apache.felix.scr.annotations.Service; 29 import org.apache.felix.scr.annotations.Service;
30 import org.onlab.onos.cluster.ClusterService; 30 import org.onlab.onos.cluster.ClusterService;
31 import org.onlab.onos.cluster.NodeId; 31 import org.onlab.onos.cluster.NodeId;
32 +import org.onlab.onos.cluster.RoleInfo;
32 import org.onlab.onos.event.AbstractListenerRegistry; 33 import org.onlab.onos.event.AbstractListenerRegistry;
33 import org.onlab.onos.event.EventDeliveryService; 34 import org.onlab.onos.event.EventDeliveryService;
34 import org.onlab.onos.mastership.MastershipEvent; 35 import org.onlab.onos.mastership.MastershipEvent;
...@@ -58,6 +59,8 @@ import org.onlab.onos.net.provider.AbstractProviderRegistry; ...@@ -58,6 +59,8 @@ import org.onlab.onos.net.provider.AbstractProviderRegistry;
58 import org.onlab.onos.net.provider.AbstractProviderService; 59 import org.onlab.onos.net.provider.AbstractProviderService;
59 import org.slf4j.Logger; 60 import org.slf4j.Logger;
60 61
62 +import com.google.common.collect.HashMultimap;
63 +
61 /** 64 /**
62 * Provides implementation of the device SB & NB APIs. 65 * Provides implementation of the device SB & NB APIs.
63 */ 66 */
...@@ -387,6 +390,12 @@ public class DeviceManager ...@@ -387,6 +390,12 @@ public class DeviceManager
387 // Intercepts mastership events 390 // Intercepts mastership events
388 private class InternalMastershipListener implements MastershipListener { 391 private class InternalMastershipListener implements MastershipListener {
389 392
393 + // random cache size
394 + private final int cacheSize = 5;
395 + // temporarily stores term number + events to check for duplicates. A hack.
396 + private HashMultimap<Integer, RoleInfo> eventCache =
397 + HashMultimap.create();
398 +
390 @Override 399 @Override
391 public void event(MastershipEvent event) { 400 public void event(MastershipEvent event) {
392 final DeviceId did = event.subject(); 401 final DeviceId did = event.subject();
...@@ -395,6 +404,13 @@ public class DeviceManager ...@@ -395,6 +404,13 @@ public class DeviceManager
395 if (myNodeId.equals(event.roleInfo().master())) { 404 if (myNodeId.equals(event.roleInfo().master())) {
396 MastershipTerm term = termService.getMastershipTerm(did); 405 MastershipTerm term = termService.getMastershipTerm(did);
397 406
407 + // TODO duplicate suppression should probably occur in the MastershipManager
408 + // itself, so listeners that can't deal with duplicates don't have to
409 + // so this check themselves.
410 + if (checkDuplicate(event.roleInfo(), term.termNumber())) {
411 + return;
412 + }
413 +
398 if (!myNodeId.equals(term.master())) { 414 if (!myNodeId.equals(term.master())) {
399 // something went wrong in consistency, let go 415 // something went wrong in consistency, let go
400 log.warn("Mastership has changed after this event." 416 log.warn("Mastership has changed after this event."
...@@ -436,6 +452,24 @@ public class DeviceManager ...@@ -436,6 +452,24 @@ public class DeviceManager
436 applyRole(did, MastershipRole.STANDBY); 452 applyRole(did, MastershipRole.STANDBY);
437 } 453 }
438 } 454 }
455 +
456 + // checks for duplicate event, returning true if one is found.
457 + private boolean checkDuplicate(RoleInfo roleInfo, int term) {
458 + synchronized (eventCache) {
459 + if (eventCache.get(term).contains(roleInfo)) {
460 + log.info("duplicate event detected; ignoring");
461 + return true;
462 + } else {
463 + eventCache.put(term, roleInfo);
464 + // purge by-term oldest entries to keep the cache size under limit
465 + if (eventCache.size() > cacheSize) {
466 + eventCache.removeAll(term - cacheSize);
467 + }
468 + return false;
469 + }
470 + }
471 + }
472 +
439 } 473 }
440 474
441 // Store delegate to re-post events emitted from the store. 475 // Store delegate to re-post events emitted from the store.
......