add check for duplicate MastershipEvents to DeviceManager
Change-Id: I2753366b29ef32fa77ebcefff4b2202f1afe0006
Showing
1 changed file
with
34 additions
and
0 deletions
... | @@ -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. | ... | ... |
-
Please register or login to post a comment