Committed by
Ray Milkey
Fixing various issues and re-tuning.
Change-Id: I8822fcf77cfa507788241c5bda98ef4741b284b4
Showing
6 changed files
with
130 additions
and
83 deletions
| ... | @@ -23,13 +23,15 @@ import org.onlab.onos.cluster.ControllerNode; | ... | @@ -23,13 +23,15 @@ import org.onlab.onos.cluster.ControllerNode; |
| 23 | import org.onlab.onos.mastership.MastershipAdminService; | 23 | import org.onlab.onos.mastership.MastershipAdminService; |
| 24 | import org.onlab.onos.mastership.MastershipService; | 24 | import org.onlab.onos.mastership.MastershipService; |
| 25 | import org.onlab.onos.net.DeviceId; | 25 | import org.onlab.onos.net.DeviceId; |
| 26 | -import org.onlab.onos.net.MastershipRole; | 26 | +import org.onlab.onos.net.device.DeviceService; |
| 27 | 27 | ||
| 28 | import java.util.Collection; | 28 | import java.util.Collection; |
| 29 | import java.util.Iterator; | 29 | import java.util.Iterator; |
| 30 | import java.util.List; | 30 | import java.util.List; |
| 31 | +import java.util.Set; | ||
| 31 | 32 | ||
| 32 | import static com.google.common.collect.Lists.newArrayList; | 33 | import static com.google.common.collect.Lists.newArrayList; |
| 34 | +import static org.onlab.onos.net.MastershipRole.MASTER; | ||
| 33 | 35 | ||
| 34 | /** | 36 | /** |
| 35 | * Forces device mastership rebalancing. | 37 | * Forces device mastership rebalancing. |
| ... | @@ -50,73 +52,62 @@ public class BalanceMastersCommand extends AbstractShellCommand { | ... | @@ -50,73 +52,62 @@ public class BalanceMastersCommand extends AbstractShellCommand { |
| 50 | 52 | ||
| 51 | // Create buckets reflecting current ownership. | 53 | // Create buckets reflecting current ownership. |
| 52 | for (ControllerNode node : nodes) { | 54 | for (ControllerNode node : nodes) { |
| 53 | - controllerDevices.putAll(node, mastershipService.getDevicesOf(node.id())); | 55 | + Set<DeviceId> devicesOf = mastershipService.getDevicesOf(node.id()); |
| 56 | + controllerDevices.putAll(node, devicesOf); | ||
| 57 | + print("Node %s has %d devices.", node.id(), devicesOf.size()); | ||
| 54 | } | 58 | } |
| 55 | 59 | ||
| 56 | - int bucketCount = nodes.size(); | 60 | + int rounds = nodes.size(); |
| 57 | - for (int i = 0; i < bucketCount / 2; i++) { | 61 | + for (int i = 0; i < rounds; i++) { |
| 58 | // Iterate over the buckets and find the smallest and the largest. | 62 | // Iterate over the buckets and find the smallest and the largest. |
| 59 | - ControllerNode smallest = findSmallestBucket(controllerDevices); | 63 | + ControllerNode smallest = findBucket(true, nodes, controllerDevices); |
| 60 | - ControllerNode largest = findLargestBucket(controllerDevices); | 64 | + ControllerNode largest = findBucket(false, nodes, controllerDevices); |
| 61 | - balanceBuckets(smallest, largest, controllerDevices, | 65 | + balanceBuckets(smallest, largest, controllerDevices, adminService); |
| 62 | - mastershipService, adminService); | ||
| 63 | } | 66 | } |
| 64 | } | 67 | } |
| 65 | 68 | ||
| 66 | - private ControllerNode findSmallestBucket(Multimap<ControllerNode, DeviceId> controllerDevices) { | 69 | + private ControllerNode findBucket(boolean min, Collection<ControllerNode> nodes, |
| 67 | - int minSize = Integer.MAX_VALUE; | 70 | + Multimap<ControllerNode, DeviceId> controllerDevices) { |
| 68 | - ControllerNode minNode = null; | 71 | + int xSize = min ? Integer.MAX_VALUE : -1; |
| 69 | - for (ControllerNode node : controllerDevices.keySet()) { | 72 | + ControllerNode xNode = null; |
| 70 | - int size = controllerDevices.get(node).size(); | 73 | + for (ControllerNode node : nodes) { |
| 71 | - if (size < minSize) { | ||
| 72 | - minSize = size; | ||
| 73 | - minNode = node; | ||
| 74 | - } | ||
| 75 | - } | ||
| 76 | - return minNode; | ||
| 77 | - } | ||
| 78 | - | ||
| 79 | - private ControllerNode findLargestBucket(Multimap<ControllerNode, DeviceId> controllerDevices) { | ||
| 80 | - int maxSize = -1; | ||
| 81 | - ControllerNode maxNode = null; | ||
| 82 | - for (ControllerNode node : controllerDevices.keySet()) { | ||
| 83 | int size = controllerDevices.get(node).size(); | 74 | int size = controllerDevices.get(node).size(); |
| 84 | - if (size >= maxSize) { | 75 | + if ((min && size < xSize) || (!min && size > xSize)) { |
| 85 | - maxSize = size; | 76 | + xSize = size; |
| 86 | - maxNode = node; | 77 | + xNode = node; |
| 87 | } | 78 | } |
| 88 | } | 79 | } |
| 89 | - return maxNode; | 80 | + return xNode; |
| 90 | } | 81 | } |
| 91 | 82 | ||
| 92 | // FIXME: enhance to better handle cases where smallest cannot take any of the devices from largest | 83 | // FIXME: enhance to better handle cases where smallest cannot take any of the devices from largest |
| 93 | 84 | ||
| 94 | private void balanceBuckets(ControllerNode smallest, ControllerNode largest, | 85 | private void balanceBuckets(ControllerNode smallest, ControllerNode largest, |
| 95 | Multimap<ControllerNode, DeviceId> controllerDevices, | 86 | Multimap<ControllerNode, DeviceId> controllerDevices, |
| 96 | - MastershipService mastershipService, | ||
| 97 | MastershipAdminService adminService) { | 87 | MastershipAdminService adminService) { |
| 98 | Collection<DeviceId> minBucket = controllerDevices.get(smallest); | 88 | Collection<DeviceId> minBucket = controllerDevices.get(smallest); |
| 99 | Collection<DeviceId> maxBucket = controllerDevices.get(largest); | 89 | Collection<DeviceId> maxBucket = controllerDevices.get(largest); |
| 90 | + int bucketCount = controllerDevices.keySet().size(); | ||
| 91 | + int deviceCount = get(DeviceService.class).getDeviceCount(); | ||
| 100 | 92 | ||
| 101 | int delta = (maxBucket.size() - minBucket.size()) / 2; | 93 | int delta = (maxBucket.size() - minBucket.size()) / 2; |
| 102 | - | 94 | + delta = Math.min(deviceCount / bucketCount, delta); |
| 103 | - print("Attempting to move %d nodes from %s to %s...", | 95 | + |
| 104 | - delta, largest.id(), smallest.id()); | 96 | + if (delta > 0) { |
| 105 | - | 97 | + print("Attempting to move %d nodes from %s to %s...", |
| 106 | - int i = 0; | 98 | + delta, largest.id(), smallest.id()); |
| 107 | - Iterator<DeviceId> it = maxBucket.iterator(); | 99 | + |
| 108 | - while (it.hasNext() && i < delta) { | 100 | + int i = 0; |
| 109 | - DeviceId deviceId = it.next(); | 101 | + Iterator<DeviceId> it = maxBucket.iterator(); |
| 110 | - | 102 | + while (it.hasNext() && i < delta) { |
| 111 | - // Check that the transfer can happen for the current element. | 103 | + DeviceId deviceId = it.next(); |
| 112 | - if (mastershipService.getNodesFor(deviceId).backups().contains(smallest.id())) { | 104 | + print("Setting %s as the master for %s", smallest.id(), deviceId); |
| 113 | - print("Setting %s as the new master for %s", smallest.id(), deviceId); | 105 | + adminService.setRole(smallest.id(), deviceId, MASTER); |
| 114 | - adminService.setRole(smallest.id(), deviceId, MastershipRole.MASTER); | 106 | + controllerDevices.put(smallest, deviceId); |
| 107 | + it.remove(); | ||
| 115 | i++; | 108 | i++; |
| 116 | } | 109 | } |
| 117 | } | 110 | } |
| 118 | - | ||
| 119 | - controllerDevices.removeAll(smallest); | ||
| 120 | } | 111 | } |
| 121 | 112 | ||
| 122 | } | 113 | } | ... | ... |
| ... | @@ -16,6 +16,8 @@ | ... | @@ -16,6 +16,8 @@ |
| 16 | package org.onlab.onos.event; | 16 | package org.onlab.onos.event; |
| 17 | 17 | ||
| 18 | import com.google.common.collect.Lists; | 18 | import com.google.common.collect.Lists; |
| 19 | +import org.slf4j.Logger; | ||
| 20 | +import org.slf4j.LoggerFactory; | ||
| 19 | 21 | ||
| 20 | import java.util.List; | 22 | import java.util.List; |
| 21 | import java.util.Timer; | 23 | import java.util.Timer; |
| ... | @@ -31,6 +33,8 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -31,6 +33,8 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 31 | */ | 33 | */ |
| 32 | public abstract class AbstractEventAccumulator implements EventAccumulator { | 34 | public abstract class AbstractEventAccumulator implements EventAccumulator { |
| 33 | 35 | ||
| 36 | + private Logger log = LoggerFactory.getLogger(AbstractEventAccumulator.class); | ||
| 37 | + | ||
| 34 | private final Timer timer; | 38 | private final Timer timer; |
| 35 | private final int maxEvents; | 39 | private final int maxEvents; |
| 36 | private final int maxBatchMillis; | 40 | private final int maxBatchMillis; |
| ... | @@ -104,9 +108,13 @@ public abstract class AbstractEventAccumulator implements EventAccumulator { | ... | @@ -104,9 +108,13 @@ public abstract class AbstractEventAccumulator implements EventAccumulator { |
| 104 | private class ProcessorTask extends TimerTask { | 108 | private class ProcessorTask extends TimerTask { |
| 105 | @Override | 109 | @Override |
| 106 | public void run() { | 110 | public void run() { |
| 107 | - idleTask = cancelIfActive(idleTask); | 111 | + try { |
| 108 | - maxTask = cancelIfActive(maxTask); | 112 | + idleTask = cancelIfActive(idleTask); |
| 109 | - processEvents(finalizeCurrentBatch()); | 113 | + maxTask = cancelIfActive(maxTask); |
| 114 | + processEvents(finalizeCurrentBatch()); | ||
| 115 | + } catch (Exception e) { | ||
| 116 | + log.warn("Unable to process batch due to {}", e.getMessage()); | ||
| 117 | + } | ||
| 110 | } | 118 | } |
| 111 | } | 119 | } |
| 112 | 120 | ... | ... |
| ... | @@ -66,13 +66,13 @@ public class DefaultTopologyProvider extends AbstractProvider | ... | @@ -66,13 +66,13 @@ public class DefaultTopologyProvider extends AbstractProvider |
| 66 | implements TopologyProvider { | 66 | implements TopologyProvider { |
| 67 | 67 | ||
| 68 | private static final int MAX_THREADS = 8; | 68 | private static final int MAX_THREADS = 8; |
| 69 | - private static final int DEFAULT_MAX_EVENTS = 100; | 69 | + private static final int DEFAULT_MAX_EVENTS = 200; |
| 70 | - private static final int DEFAULT_MAX_BATCH_MS = 50; | 70 | + private static final int DEFAULT_MAX_BATCH_MS = 60; |
| 71 | - private static final int DEFAULT_MAX_IDLE_MS = 5; | 71 | + private static final int DEFAULT_MAX_IDLE_MS = 30; |
| 72 | 72 | ||
| 73 | // FIXME: Replace with a system-wide timer instance; | 73 | // FIXME: Replace with a system-wide timer instance; |
| 74 | // TODO: Convert to use HashedWheelTimer or produce a variant of that; then decide which we want to adopt | 74 | // TODO: Convert to use HashedWheelTimer or produce a variant of that; then decide which we want to adopt |
| 75 | - private static final Timer TIMER = new Timer(); | 75 | + private static final Timer TIMER = new Timer("topo-event-batching"); |
| 76 | 76 | ||
| 77 | @Property(name = "maxEvents", intValue = DEFAULT_MAX_EVENTS, | 77 | @Property(name = "maxEvents", intValue = DEFAULT_MAX_EVENTS, |
| 78 | label = "Maximum number of events to accumulate") | 78 | label = "Maximum number of events to accumulate") |
| ... | @@ -122,6 +122,9 @@ public class DefaultTopologyProvider extends AbstractProvider | ... | @@ -122,6 +122,9 @@ public class DefaultTopologyProvider extends AbstractProvider |
| 122 | deviceService.addListener(deviceListener); | 122 | deviceService.addListener(deviceListener); |
| 123 | linkService.addListener(linkListener); | 123 | linkService.addListener(linkListener); |
| 124 | 124 | ||
| 125 | + log.info("Configured with maxEvents = {}; maxBatchMs = {}; maxIdleMs = {}", | ||
| 126 | + maxEvents, maxBatchMs, maxIdleMs); | ||
| 127 | + | ||
| 125 | isStarted = true; | 128 | isStarted = true; |
| 126 | triggerRecompute(); | 129 | triggerRecompute(); |
| 127 | log.info("Started"); | 130 | log.info("Started"); | ... | ... |
tools/test/bin/onos-topo-cfg-all
0 → 100755
| 1 | +#!/bin/bash | ||
| 2 | +# ----------------------------------------------------------------------------- | ||
| 3 | +# ONOS topology configuration uploader. | ||
| 4 | +# ----------------------------------------------------------------------------- | ||
| 5 | + | ||
| 6 | +[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1 | ||
| 7 | +. $ONOS_ROOT/tools/build/envDefaults | ||
| 8 | + | ||
| 9 | +nodes=$(env | sort | egrep "OC[0-9]+" | cut -d= -f2) | ||
| 10 | + | ||
| 11 | +for node in $nodes; do | ||
| 12 | + printf "$node..." | ||
| 13 | + onos-topo-cfg $node $1 | ||
| 14 | +done | ||
| 15 | +printf "\n" |
| ... | @@ -24,6 +24,9 @@ import org.onlab.onos.cluster.ClusterEventListener; | ... | @@ -24,6 +24,9 @@ import org.onlab.onos.cluster.ClusterEventListener; |
| 24 | import org.onlab.onos.cluster.ControllerNode; | 24 | import org.onlab.onos.cluster.ControllerNode; |
| 25 | import org.onlab.onos.core.ApplicationId; | 25 | import org.onlab.onos.core.ApplicationId; |
| 26 | import org.onlab.onos.core.CoreService; | 26 | import org.onlab.onos.core.CoreService; |
| 27 | +import org.onlab.onos.event.AbstractEventAccumulator; | ||
| 28 | +import org.onlab.onos.event.Event; | ||
| 29 | +import org.onlab.onos.event.EventAccumulator; | ||
| 27 | import org.onlab.onos.mastership.MastershipEvent; | 30 | import org.onlab.onos.mastership.MastershipEvent; |
| 28 | import org.onlab.onos.mastership.MastershipListener; | 31 | import org.onlab.onos.mastership.MastershipListener; |
| 29 | import org.onlab.onos.net.ConnectPoint; | 32 | import org.onlab.onos.net.ConnectPoint; |
| ... | @@ -36,6 +39,8 @@ import org.onlab.onos.net.device.DeviceEvent; | ... | @@ -36,6 +39,8 @@ import org.onlab.onos.net.device.DeviceEvent; |
| 36 | import org.onlab.onos.net.device.DeviceListener; | 39 | import org.onlab.onos.net.device.DeviceListener; |
| 37 | import org.onlab.onos.net.flow.DefaultTrafficSelector; | 40 | import org.onlab.onos.net.flow.DefaultTrafficSelector; |
| 38 | import org.onlab.onos.net.flow.DefaultTrafficTreatment; | 41 | import org.onlab.onos.net.flow.DefaultTrafficTreatment; |
| 42 | +import org.onlab.onos.net.flow.FlowRuleEvent; | ||
| 43 | +import org.onlab.onos.net.flow.FlowRuleListener; | ||
| 39 | import org.onlab.onos.net.flow.TrafficSelector; | 44 | import org.onlab.onos.net.flow.TrafficSelector; |
| 40 | import org.onlab.onos.net.flow.TrafficTreatment; | 45 | import org.onlab.onos.net.flow.TrafficTreatment; |
| 41 | import org.onlab.onos.net.host.HostEvent; | 46 | import org.onlab.onos.net.host.HostEvent; |
| ... | @@ -84,8 +89,7 @@ public class TopologyViewWebSocket | ... | @@ -84,8 +89,7 @@ public class TopologyViewWebSocket |
| 84 | 89 | ||
| 85 | private static final String APP_ID = "org.onlab.onos.gui"; | 90 | private static final String APP_ID = "org.onlab.onos.gui"; |
| 86 | 91 | ||
| 87 | - private static final long SUMMARY_FREQUENCY_SEC = 3000; | 92 | + private static final long TRAFFIC_FREQUENCY_SEC = 2000; |
| 88 | - private static final long TRAFFIC_FREQUENCY_SEC = 1500; | ||
| 89 | 93 | ||
| 90 | private static final Comparator<? super ControllerNode> NODE_COMPARATOR = | 94 | private static final Comparator<? super ControllerNode> NODE_COMPARATOR = |
| 91 | new Comparator<ControllerNode>() { | 95 | new Comparator<ControllerNode>() { |
| ... | @@ -95,6 +99,13 @@ public class TopologyViewWebSocket | ... | @@ -95,6 +99,13 @@ public class TopologyViewWebSocket |
| 95 | } | 99 | } |
| 96 | }; | 100 | }; |
| 97 | 101 | ||
| 102 | + | ||
| 103 | + private final Timer timer = new Timer("topology-view"); | ||
| 104 | + | ||
| 105 | + private static final int MAX_EVENTS = 500; | ||
| 106 | + private static final int MAX_BATCH_MS = 1000; | ||
| 107 | + private static final int MAX_IDLE_MS = 500; | ||
| 108 | + | ||
| 98 | private final ApplicationId appId; | 109 | private final ApplicationId appId; |
| 99 | 110 | ||
| 100 | private Connection connection; | 111 | private Connection connection; |
| ... | @@ -106,16 +117,14 @@ public class TopologyViewWebSocket | ... | @@ -106,16 +117,14 @@ public class TopologyViewWebSocket |
| 106 | private final LinkListener linkListener = new InternalLinkListener(); | 117 | private final LinkListener linkListener = new InternalLinkListener(); |
| 107 | private final HostListener hostListener = new InternalHostListener(); | 118 | private final HostListener hostListener = new InternalHostListener(); |
| 108 | private final IntentListener intentListener = new InternalIntentListener(); | 119 | private final IntentListener intentListener = new InternalIntentListener(); |
| 120 | + private final FlowRuleListener flowListener = new InternalFlowListener(); | ||
| 109 | 121 | ||
| 110 | - // Timers and objects being monitored | 122 | + private final EventAccumulator eventAccummulator = new InternalEventAccummulator(); |
| 111 | - private final Timer timer = new Timer("topology-view"); | ||
| 112 | 123 | ||
| 124 | + private boolean summaryEnabled = true; | ||
| 113 | private TimerTask trafficTask; | 125 | private TimerTask trafficTask; |
| 114 | private ObjectNode trafficEvent; | 126 | private ObjectNode trafficEvent; |
| 115 | 127 | ||
| 116 | - private TimerTask summaryTask; | ||
| 117 | - private ObjectNode summaryEvent; | ||
| 118 | - | ||
| 119 | private long lastActive = System.currentTimeMillis(); | 128 | private long lastActive = System.currentTimeMillis(); |
| 120 | private boolean listenersRemoved = false; | 129 | private boolean listenersRemoved = false; |
| 121 | 130 | ||
| ... | @@ -128,7 +137,6 @@ public class TopologyViewWebSocket | ... | @@ -128,7 +137,6 @@ public class TopologyViewWebSocket |
| 128 | */ | 137 | */ |
| 129 | public TopologyViewWebSocket(ServiceDirectory directory) { | 138 | public TopologyViewWebSocket(ServiceDirectory directory) { |
| 130 | super(directory); | 139 | super(directory); |
| 131 | - | ||
| 132 | intentFilter = new TopologyViewIntentFilter(intentService, deviceService, | 140 | intentFilter = new TopologyViewIntentFilter(intentService, deviceService, |
| 133 | hostService, linkService); | 141 | hostService, linkService); |
| 134 | appId = directory.get(CoreService.class).registerApplication(APP_ID); | 142 | appId = directory.get(CoreService.class).registerApplication(APP_ID); |
| ... | @@ -431,21 +439,13 @@ public class TopologyViewWebSocket | ... | @@ -431,21 +439,13 @@ public class TopologyViewWebSocket |
| 431 | 439 | ||
| 432 | // Subscribes for summary messages. | 440 | // Subscribes for summary messages. |
| 433 | private synchronized void requestSummary(ObjectNode event) { | 441 | private synchronized void requestSummary(ObjectNode event) { |
| 434 | - if (summaryTask == null) { | 442 | + summaryEnabled = true; |
| 435 | - summaryEvent = event; | ||
| 436 | - summaryTask = new SummaryMonitor(); | ||
| 437 | - timer.schedule(summaryTask, SUMMARY_FREQUENCY_SEC, SUMMARY_FREQUENCY_SEC); | ||
| 438 | - } | ||
| 439 | sendMessage(summmaryMessage(number(event, "sid"))); | 443 | sendMessage(summmaryMessage(number(event, "sid"))); |
| 440 | } | 444 | } |
| 441 | 445 | ||
| 442 | // Cancels sending summary messages. | 446 | // Cancels sending summary messages. |
| 443 | private synchronized void cancelSummary(ObjectNode event) { | 447 | private synchronized void cancelSummary(ObjectNode event) { |
| 444 | - if (summaryTask != null) { | 448 | + summaryEnabled = false; |
| 445 | - summaryTask.cancel(); | ||
| 446 | - summaryTask = null; | ||
| 447 | - summaryEvent = null; | ||
| 448 | - } | ||
| 449 | } | 449 | } |
| 450 | 450 | ||
| 451 | 451 | ||
| ... | @@ -457,6 +457,7 @@ public class TopologyViewWebSocket | ... | @@ -457,6 +457,7 @@ public class TopologyViewWebSocket |
| 457 | linkService.addListener(linkListener); | 457 | linkService.addListener(linkListener); |
| 458 | hostService.addListener(hostListener); | 458 | hostService.addListener(hostListener); |
| 459 | intentService.addListener(intentListener); | 459 | intentService.addListener(intentListener); |
| 460 | + flowService.addListener(flowListener); | ||
| 460 | } | 461 | } |
| 461 | 462 | ||
| 462 | // Removes all internal listeners. | 463 | // Removes all internal listeners. |
| ... | @@ -469,6 +470,7 @@ public class TopologyViewWebSocket | ... | @@ -469,6 +470,7 @@ public class TopologyViewWebSocket |
| 469 | linkService.removeListener(linkListener); | 470 | linkService.removeListener(linkListener); |
| 470 | hostService.removeListener(hostListener); | 471 | hostService.removeListener(hostListener); |
| 471 | intentService.removeListener(intentListener); | 472 | intentService.removeListener(intentListener); |
| 473 | + flowService.removeListener(flowListener); | ||
| 472 | } | 474 | } |
| 473 | } | 475 | } |
| 474 | 476 | ||
| ... | @@ -495,6 +497,7 @@ public class TopologyViewWebSocket | ... | @@ -495,6 +497,7 @@ public class TopologyViewWebSocket |
| 495 | @Override | 497 | @Override |
| 496 | public void event(DeviceEvent event) { | 498 | public void event(DeviceEvent event) { |
| 497 | sendMessage(deviceMessage(event)); | 499 | sendMessage(deviceMessage(event)); |
| 500 | + eventAccummulator.add(event); | ||
| 498 | } | 501 | } |
| 499 | } | 502 | } |
| 500 | 503 | ||
| ... | @@ -503,6 +506,7 @@ public class TopologyViewWebSocket | ... | @@ -503,6 +506,7 @@ public class TopologyViewWebSocket |
| 503 | @Override | 506 | @Override |
| 504 | public void event(LinkEvent event) { | 507 | public void event(LinkEvent event) { |
| 505 | sendMessage(linkMessage(event)); | 508 | sendMessage(linkMessage(event)); |
| 509 | + eventAccummulator.add(event); | ||
| 506 | } | 510 | } |
| 507 | } | 511 | } |
| 508 | 512 | ||
| ... | @@ -511,6 +515,7 @@ public class TopologyViewWebSocket | ... | @@ -511,6 +515,7 @@ public class TopologyViewWebSocket |
| 511 | @Override | 515 | @Override |
| 512 | public void event(HostEvent event) { | 516 | public void event(HostEvent event) { |
| 513 | sendMessage(hostMessage(event)); | 517 | sendMessage(hostMessage(event)); |
| 518 | + eventAccummulator.add(event); | ||
| 514 | } | 519 | } |
| 515 | } | 520 | } |
| 516 | 521 | ||
| ... | @@ -521,33 +526,55 @@ public class TopologyViewWebSocket | ... | @@ -521,33 +526,55 @@ public class TopologyViewWebSocket |
| 521 | if (trafficEvent != null) { | 526 | if (trafficEvent != null) { |
| 522 | requestTraffic(trafficEvent); | 527 | requestTraffic(trafficEvent); |
| 523 | } | 528 | } |
| 529 | + eventAccummulator.add(event); | ||
| 530 | + } | ||
| 531 | + } | ||
| 532 | + | ||
| 533 | + // Intent event listener. | ||
| 534 | + private class InternalFlowListener implements FlowRuleListener { | ||
| 535 | + @Override | ||
| 536 | + public void event(FlowRuleEvent event) { | ||
| 537 | + eventAccummulator.add(event); | ||
| 524 | } | 538 | } |
| 525 | } | 539 | } |
| 526 | 540 | ||
| 527 | private class TrafficMonitor extends TimerTask { | 541 | private class TrafficMonitor extends TimerTask { |
| 528 | @Override | 542 | @Override |
| 529 | public void run() { | 543 | public void run() { |
| 530 | - if (trafficEvent != null) { | 544 | + try { |
| 531 | - String type = string(trafficEvent, "event", "unknown"); | 545 | + if (trafficEvent != null) { |
| 532 | - if (type.equals("requestAllTraffic")) { | 546 | + String type = string(trafficEvent, "event", "unknown"); |
| 533 | - requestAllTraffic(trafficEvent); | 547 | + if (type.equals("requestAllTraffic")) { |
| 534 | - } else if (type.equals("requestDeviceLinkFlows")) { | 548 | + requestAllTraffic(trafficEvent); |
| 535 | - requestDeviceLinkFlows(trafficEvent); | 549 | + } else if (type.equals("requestDeviceLinkFlows")) { |
| 536 | - } else { | 550 | + requestDeviceLinkFlows(trafficEvent); |
| 537 | - requestTraffic(trafficEvent); | 551 | + } else { |
| 552 | + requestTraffic(trafficEvent); | ||
| 553 | + } | ||
| 538 | } | 554 | } |
| 555 | + } catch (Exception e) { | ||
| 556 | + log.warn("Unable to handle traffic request due to {}", e.getMessage()); | ||
| 539 | } | 557 | } |
| 540 | } | 558 | } |
| 541 | } | 559 | } |
| 542 | 560 | ||
| 543 | - private class SummaryMonitor extends TimerTask { | 561 | + // Accummulates events to drive methodic update of the summary pane. |
| 562 | + private class InternalEventAccummulator extends AbstractEventAccumulator { | ||
| 563 | + protected InternalEventAccummulator() { | ||
| 564 | + super(new Timer("topo-summary"), MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS); | ||
| 565 | + } | ||
| 566 | + | ||
| 544 | @Override | 567 | @Override |
| 545 | - public void run() { | 568 | + public void processEvents(List<Event> events) { |
| 546 | - if (summaryEvent != null) { | 569 | + try { |
| 547 | - requestSummary(summaryEvent); | 570 | + if (summaryEnabled) { |
| 571 | + sendMessage(summmaryMessage(0)); | ||
| 572 | + } | ||
| 573 | + } catch (Exception e) { | ||
| 574 | + log.warn("Unable to handle summary request due to {}", e.getMessage()); | ||
| 548 | } | 575 | } |
| 576 | + | ||
| 549 | } | 577 | } |
| 550 | } | 578 | } |
| 551 | - | ||
| 552 | } | 579 | } |
| 553 | 580 | ... | ... |
| ... | @@ -356,6 +356,9 @@ | ... | @@ -356,6 +356,9 @@ |
| 356 | hideInstances(); | 356 | hideInstances(); |
| 357 | } else if (summaryPane.isVisible()) { | 357 | } else if (summaryPane.isVisible()) { |
| 358 | cancelSummary(); | 358 | cancelSummary(); |
| 359 | + stopAntTimer(); | ||
| 360 | + } else { | ||
| 361 | + hoverMode = hoverModeFlows; | ||
| 359 | } | 362 | } |
| 360 | } | 363 | } |
| 361 | 364 | ... | ... |
-
Please register or login to post a comment