Committed by
Gerrit Code Review
Adding configurability to the even accumulator for the topology provider.
Change-Id: I35ede9a62782dc6a2e55b8895aeec6ece8836960
Showing
3 changed files
with
77 additions
and
12 deletions
| ... | @@ -58,6 +58,11 @@ | ... | @@ -58,6 +58,11 @@ |
| 58 | </dependency> | 58 | </dependency> |
| 59 | 59 | ||
| 60 | <dependency> | 60 | <dependency> |
| 61 | + <groupId>org.osgi</groupId> | ||
| 62 | + <artifactId>org.osgi.compendium</artifactId> | ||
| 63 | + </dependency> | ||
| 64 | + | ||
| 65 | + <dependency> | ||
| 61 | <groupId>org.apache.felix</groupId> | 66 | <groupId>org.apache.felix</groupId> |
| 62 | <artifactId>org.apache.felix.scr.annotations</artifactId> | 67 | <artifactId>org.apache.felix.scr.annotations</artifactId> |
| 63 | </dependency> | 68 | </dependency> | ... | ... |
| ... | @@ -15,9 +15,12 @@ | ... | @@ -15,9 +15,12 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onlab.onos.net.topology.impl; | 16 | package org.onlab.onos.net.topology.impl; |
| 17 | 17 | ||
| 18 | +import com.google.common.collect.ImmutableList; | ||
| 18 | import org.apache.felix.scr.annotations.Activate; | 19 | import org.apache.felix.scr.annotations.Activate; |
| 19 | import org.apache.felix.scr.annotations.Component; | 20 | import org.apache.felix.scr.annotations.Component; |
| 20 | import org.apache.felix.scr.annotations.Deactivate; | 21 | import org.apache.felix.scr.annotations.Deactivate; |
| 22 | +import org.apache.felix.scr.annotations.Modified; | ||
| 23 | +import org.apache.felix.scr.annotations.Property; | ||
| 21 | import org.apache.felix.scr.annotations.Reference; | 24 | import org.apache.felix.scr.annotations.Reference; |
| 22 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 25 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 23 | import org.apache.felix.scr.annotations.Service; | 26 | import org.apache.felix.scr.annotations.Service; |
| ... | @@ -36,13 +39,16 @@ import org.onlab.onos.net.topology.GraphDescription; | ... | @@ -36,13 +39,16 @@ import org.onlab.onos.net.topology.GraphDescription; |
| 36 | import org.onlab.onos.net.topology.TopologyProvider; | 39 | import org.onlab.onos.net.topology.TopologyProvider; |
| 37 | import org.onlab.onos.net.topology.TopologyProviderRegistry; | 40 | import org.onlab.onos.net.topology.TopologyProviderRegistry; |
| 38 | import org.onlab.onos.net.topology.TopologyProviderService; | 41 | import org.onlab.onos.net.topology.TopologyProviderService; |
| 42 | +import org.osgi.service.component.ComponentContext; | ||
| 39 | import org.slf4j.Logger; | 43 | import org.slf4j.Logger; |
| 40 | 44 | ||
| 41 | import java.util.Collections; | 45 | import java.util.Collections; |
| 46 | +import java.util.Dictionary; | ||
| 42 | import java.util.List; | 47 | import java.util.List; |
| 43 | import java.util.Timer; | 48 | import java.util.Timer; |
| 44 | import java.util.concurrent.ExecutorService; | 49 | import java.util.concurrent.ExecutorService; |
| 45 | 50 | ||
| 51 | +import static com.google.common.base.Strings.isNullOrEmpty; | ||
| 46 | import static java.util.concurrent.Executors.newFixedThreadPool; | 52 | import static java.util.concurrent.Executors.newFixedThreadPool; |
| 47 | import static org.onlab.onos.core.CoreService.CORE_PROVIDER_ID; | 53 | import static org.onlab.onos.core.CoreService.CORE_PROVIDER_ID; |
| 48 | import static org.onlab.onos.net.device.DeviceEvent.Type.*; | 54 | import static org.onlab.onos.net.device.DeviceEvent.Type.*; |
| ... | @@ -59,16 +65,27 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -59,16 +65,27 @@ import static org.slf4j.LoggerFactory.getLogger; |
| 59 | public class DefaultTopologyProvider extends AbstractProvider | 65 | public class DefaultTopologyProvider extends AbstractProvider |
| 60 | implements TopologyProvider { | 66 | implements TopologyProvider { |
| 61 | 67 | ||
| 62 | - // TODO: make these configurable | ||
| 63 | - private static final int MAX_EVENTS = 100; | ||
| 64 | - private static final int MAX_IDLE_MS = 5; | ||
| 65 | - private static final int MAX_BATCH_MS = 50; | ||
| 66 | private static final int MAX_THREADS = 8; | 68 | private static final int MAX_THREADS = 8; |
| 69 | + private static final int DEFAULT_MAX_EVENTS = 100; | ||
| 70 | + private static final int DEFAULT_MAX_BATCH_MS = 50; | ||
| 71 | + private static final int DEFAULT_MAX_IDLE_MS = 5; | ||
| 67 | 72 | ||
| 68 | // FIXME: Replace with a system-wide timer instance; | 73 | // FIXME: Replace with a system-wide timer instance; |
| 69 | // 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 |
| 70 | private static final Timer TIMER = new Timer(); | 75 | private static final Timer TIMER = new Timer(); |
| 71 | 76 | ||
| 77 | + @Property(name = "maxEvents", intValue = DEFAULT_MAX_EVENTS, | ||
| 78 | + label = "Maximum number of events to accumulate") | ||
| 79 | + private int maxEvents = DEFAULT_MAX_EVENTS; | ||
| 80 | + | ||
| 81 | + @Property(name = "maxIdleMs", intValue = DEFAULT_MAX_IDLE_MS, | ||
| 82 | + label = "Maximum number of millis between events") | ||
| 83 | + private int maxIdleMs = DEFAULT_MAX_IDLE_MS; | ||
| 84 | + | ||
| 85 | + @Property(name = "maxBatchMs", intValue = DEFAULT_MAX_BATCH_MS, | ||
| 86 | + label = "Maximum number of millis for whole batch") | ||
| 87 | + private int maxBatchMs = DEFAULT_MAX_BATCH_MS; | ||
| 88 | + | ||
| 72 | private final Logger log = getLogger(getClass()); | 89 | private final Logger log = getLogger(getClass()); |
| 73 | 90 | ||
| 74 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 91 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| ... | @@ -97,9 +114,9 @@ public class DefaultTopologyProvider extends AbstractProvider | ... | @@ -97,9 +114,9 @@ public class DefaultTopologyProvider extends AbstractProvider |
| 97 | } | 114 | } |
| 98 | 115 | ||
| 99 | @Activate | 116 | @Activate |
| 100 | - public synchronized void activate() { | 117 | + public synchronized void activate(ComponentContext context) { |
| 101 | executor = newFixedThreadPool(MAX_THREADS, namedThreads("topo-build-%d")); | 118 | executor = newFixedThreadPool(MAX_THREADS, namedThreads("topo-build-%d")); |
| 102 | - accumulator = new TopologyChangeAccumulator(); | 119 | + modified(context); |
| 103 | 120 | ||
| 104 | providerService = providerRegistry.register(this); | 121 | providerService = providerRegistry.register(this); |
| 105 | deviceService.addListener(deviceListener); | 122 | deviceService.addListener(deviceListener); |
| ... | @@ -111,7 +128,7 @@ public class DefaultTopologyProvider extends AbstractProvider | ... | @@ -111,7 +128,7 @@ public class DefaultTopologyProvider extends AbstractProvider |
| 111 | } | 128 | } |
| 112 | 129 | ||
| 113 | @Deactivate | 130 | @Deactivate |
| 114 | - public synchronized void deactivate() { | 131 | + public synchronized void deactivate(ComponentContext context) { |
| 115 | isStarted = false; | 132 | isStarted = false; |
| 116 | 133 | ||
| 117 | deviceService.removeListener(deviceListener); | 134 | deviceService.removeListener(deviceListener); |
| ... | @@ -125,6 +142,41 @@ public class DefaultTopologyProvider extends AbstractProvider | ... | @@ -125,6 +142,41 @@ public class DefaultTopologyProvider extends AbstractProvider |
| 125 | log.info("Stopped"); | 142 | log.info("Stopped"); |
| 126 | } | 143 | } |
| 127 | 144 | ||
| 145 | + @Modified | ||
| 146 | + public void modified(ComponentContext context) { | ||
| 147 | + if (context == null) { | ||
| 148 | + accumulator = new TopologyChangeAccumulator(); | ||
| 149 | + return; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + Dictionary properties = context.getProperties(); | ||
| 153 | + int newMaxEvents, newMaxBatchMs, newMaxIdleMs; | ||
| 154 | + try { | ||
| 155 | + String s = (String) properties.get("maxEvents"); | ||
| 156 | + newMaxEvents = isNullOrEmpty(s) ? maxEvents : Integer.parseInt(s); | ||
| 157 | + | ||
| 158 | + s = (String) properties.get("maxBatchMs"); | ||
| 159 | + newMaxBatchMs = isNullOrEmpty(s) ? maxBatchMs : Integer.parseInt(s); | ||
| 160 | + | ||
| 161 | + s = (String) properties.get("maxIdleMs"); | ||
| 162 | + newMaxIdleMs = isNullOrEmpty(s) ? maxIdleMs : Integer.parseInt(s); | ||
| 163 | + } catch (Exception e) { | ||
| 164 | + newMaxEvents = DEFAULT_MAX_EVENTS; | ||
| 165 | + newMaxBatchMs = DEFAULT_MAX_BATCH_MS; | ||
| 166 | + newMaxIdleMs = DEFAULT_MAX_IDLE_MS; | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + if (newMaxEvents != maxEvents || newMaxBatchMs != maxBatchMs || newMaxIdleMs != maxIdleMs) { | ||
| 170 | + maxEvents = newMaxEvents; | ||
| 171 | + maxBatchMs = newMaxBatchMs; | ||
| 172 | + maxIdleMs = newMaxIdleMs; | ||
| 173 | + accumulator = maxEvents > 1 ? new TopologyChangeAccumulator() : null; | ||
| 174 | + log.info("Reconfigured with maxEvents = {}; maxBatchMs = {}; maxIdleMs = {}", | ||
| 175 | + maxEvents, maxBatchMs, maxIdleMs); | ||
| 176 | + } | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + | ||
| 128 | @Override | 180 | @Override |
| 129 | public void triggerRecompute() { | 181 | public void triggerRecompute() { |
| 130 | triggerTopologyBuild(Collections.<Event>emptyList()); | 182 | triggerTopologyBuild(Collections.<Event>emptyList()); |
| ... | @@ -154,6 +206,14 @@ public class DefaultTopologyProvider extends AbstractProvider | ... | @@ -154,6 +206,14 @@ public class DefaultTopologyProvider extends AbstractProvider |
| 154 | } | 206 | } |
| 155 | } | 207 | } |
| 156 | 208 | ||
| 209 | + private void processEvent(Event event) { | ||
| 210 | + if (accumulator != null) { | ||
| 211 | + accumulator.add(event); | ||
| 212 | + } else { | ||
| 213 | + triggerTopologyBuild(ImmutableList.of(event)); | ||
| 214 | + } | ||
| 215 | + } | ||
| 216 | + | ||
| 157 | // Callback for device events | 217 | // Callback for device events |
| 158 | private class InternalDeviceListener implements DeviceListener { | 218 | private class InternalDeviceListener implements DeviceListener { |
| 159 | @Override | 219 | @Override |
| ... | @@ -161,7 +221,7 @@ public class DefaultTopologyProvider extends AbstractProvider | ... | @@ -161,7 +221,7 @@ public class DefaultTopologyProvider extends AbstractProvider |
| 161 | DeviceEvent.Type type = event.type(); | 221 | DeviceEvent.Type type = event.type(); |
| 162 | if (type == DEVICE_ADDED || type == DEVICE_REMOVED || | 222 | if (type == DEVICE_ADDED || type == DEVICE_REMOVED || |
| 163 | type == DEVICE_AVAILABILITY_CHANGED) { | 223 | type == DEVICE_AVAILABILITY_CHANGED) { |
| 164 | - accumulator.add(event); | 224 | + processEvent(event); |
| 165 | } | 225 | } |
| 166 | } | 226 | } |
| 167 | } | 227 | } |
| ... | @@ -170,7 +230,7 @@ public class DefaultTopologyProvider extends AbstractProvider | ... | @@ -170,7 +230,7 @@ public class DefaultTopologyProvider extends AbstractProvider |
| 170 | private class InternalLinkListener implements LinkListener { | 230 | private class InternalLinkListener implements LinkListener { |
| 171 | @Override | 231 | @Override |
| 172 | public void event(LinkEvent event) { | 232 | public void event(LinkEvent event) { |
| 173 | - accumulator.add(event); | 233 | + processEvent(event); |
| 174 | } | 234 | } |
| 175 | } | 235 | } |
| 176 | 236 | ||
| ... | @@ -179,7 +239,7 @@ public class DefaultTopologyProvider extends AbstractProvider | ... | @@ -179,7 +239,7 @@ public class DefaultTopologyProvider extends AbstractProvider |
| 179 | extends AbstractEventAccumulator implements EventAccumulator { | 239 | extends AbstractEventAccumulator implements EventAccumulator { |
| 180 | 240 | ||
| 181 | TopologyChangeAccumulator() { | 241 | TopologyChangeAccumulator() { |
| 182 | - super(TIMER, MAX_EVENTS, MAX_BATCH_MS, MAX_IDLE_MS); | 242 | + super(TIMER, maxEvents, maxBatchMs, maxIdleMs); |
| 183 | } | 243 | } |
| 184 | 244 | ||
| 185 | @Override | 245 | @Override | ... | ... |
| ... | @@ -67,12 +67,12 @@ public class DefaultTopologyProviderTest { | ... | @@ -67,12 +67,12 @@ public class DefaultTopologyProviderTest { |
| 67 | provider.deviceService = deviceService; | 67 | provider.deviceService = deviceService; |
| 68 | provider.linkService = linkService; | 68 | provider.linkService = linkService; |
| 69 | provider.providerRegistry = topologyService; | 69 | provider.providerRegistry = topologyService; |
| 70 | - provider.activate(); | 70 | + provider.activate(null); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | @After | 73 | @After |
| 74 | public void tearDown() { | 74 | public void tearDown() { |
| 75 | - provider.deactivate(); | 75 | + provider.deactivate(null); |
| 76 | provider.providerRegistry = null; | 76 | provider.providerRegistry = null; |
| 77 | provider.deviceService = null; | 77 | provider.deviceService = null; |
| 78 | provider.linkService = null; | 78 | provider.linkService = null; | ... | ... |
-
Please register or login to post a comment