Committed by
Gerrit Code Review
Fix ONOS-4683 - Don't process device events on the listener thread
Change-Id: Icc465311c2c047dba11bacc69c745bbda55ea714
Showing
3 changed files
with
76 additions
and
45 deletions
| ... | @@ -15,9 +15,16 @@ | ... | @@ -15,9 +15,16 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.provider.lldp.impl; | 16 | package org.onosproject.provider.lldp.impl; |
| 17 | 17 | ||
| 18 | -import com.google.common.collect.ImmutableMap; | 18 | +import java.util.Dictionary; |
| 19 | -import com.google.common.collect.ImmutableSet; | 19 | +import java.util.EnumSet; |
| 20 | -import com.google.common.collect.Maps; | 20 | +import java.util.Map; |
| 21 | +import java.util.Optional; | ||
| 22 | +import java.util.Properties; | ||
| 23 | +import java.util.Set; | ||
| 24 | +import java.util.concurrent.ConcurrentHashMap; | ||
| 25 | +import java.util.concurrent.ExecutorService; | ||
| 26 | +import java.util.concurrent.ScheduledExecutorService; | ||
| 27 | + | ||
| 21 | import org.apache.felix.scr.annotations.Activate; | 28 | import org.apache.felix.scr.annotations.Activate; |
| 22 | import org.apache.felix.scr.annotations.Component; | 29 | import org.apache.felix.scr.annotations.Component; |
| 23 | import org.apache.felix.scr.annotations.Deactivate; | 30 | import org.apache.felix.scr.annotations.Deactivate; |
| ... | @@ -26,7 +33,6 @@ import org.apache.felix.scr.annotations.Property; | ... | @@ -26,7 +33,6 @@ import org.apache.felix.scr.annotations.Property; |
| 26 | import org.apache.felix.scr.annotations.Reference; | 33 | import org.apache.felix.scr.annotations.Reference; |
| 27 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 34 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
| 28 | import org.onlab.packet.Ethernet; | 35 | import org.onlab.packet.Ethernet; |
| 29 | -import org.onlab.util.SharedExecutors; | ||
| 30 | import org.onosproject.cfg.ComponentConfigService; | 36 | import org.onosproject.cfg.ComponentConfigService; |
| 31 | import org.onosproject.cluster.ClusterMetadataService; | 37 | import org.onosproject.cluster.ClusterMetadataService; |
| 32 | import org.onosproject.cluster.ClusterService; | 38 | import org.onosproject.cluster.ClusterService; |
| ... | @@ -51,29 +57,24 @@ import org.onosproject.net.device.DeviceService; | ... | @@ -51,29 +57,24 @@ import org.onosproject.net.device.DeviceService; |
| 51 | import org.onosproject.net.flow.DefaultTrafficSelector; | 57 | import org.onosproject.net.flow.DefaultTrafficSelector; |
| 52 | import org.onosproject.net.flow.TrafficSelector; | 58 | import org.onosproject.net.flow.TrafficSelector; |
| 53 | import org.onosproject.net.link.DefaultLinkDescription; | 59 | import org.onosproject.net.link.DefaultLinkDescription; |
| 54 | -import org.onosproject.net.link.ProbedLinkProvider; | ||
| 55 | import org.onosproject.net.link.LinkProviderRegistry; | 60 | import org.onosproject.net.link.LinkProviderRegistry; |
| 56 | import org.onosproject.net.link.LinkProviderService; | 61 | import org.onosproject.net.link.LinkProviderService; |
| 57 | import org.onosproject.net.link.LinkService; | 62 | import org.onosproject.net.link.LinkService; |
| 63 | +import org.onosproject.net.link.ProbedLinkProvider; | ||
| 58 | import org.onosproject.net.packet.PacketContext; | 64 | import org.onosproject.net.packet.PacketContext; |
| 59 | import org.onosproject.net.packet.PacketPriority; | 65 | import org.onosproject.net.packet.PacketPriority; |
| 60 | import org.onosproject.net.packet.PacketProcessor; | 66 | import org.onosproject.net.packet.PacketProcessor; |
| 61 | import org.onosproject.net.packet.PacketService; | 67 | import org.onosproject.net.packet.PacketService; |
| 62 | import org.onosproject.net.provider.AbstractProvider; | 68 | import org.onosproject.net.provider.AbstractProvider; |
| 63 | import org.onosproject.net.provider.ProviderId; | 69 | import org.onosproject.net.provider.ProviderId; |
| 64 | -import org.onosproject.provider.lldpcommon.LinkDiscoveryContext; | ||
| 65 | import org.onosproject.provider.lldpcommon.LinkDiscovery; | 70 | import org.onosproject.provider.lldpcommon.LinkDiscovery; |
| 71 | +import org.onosproject.provider.lldpcommon.LinkDiscoveryContext; | ||
| 66 | import org.osgi.service.component.ComponentContext; | 72 | import org.osgi.service.component.ComponentContext; |
| 67 | import org.slf4j.Logger; | 73 | import org.slf4j.Logger; |
| 68 | 74 | ||
| 69 | -import java.util.Dictionary; | 75 | +import com.google.common.collect.ImmutableMap; |
| 70 | -import java.util.EnumSet; | 76 | +import com.google.common.collect.ImmutableSet; |
| 71 | -import java.util.Map; | 77 | +import com.google.common.collect.Maps; |
| 72 | -import java.util.Optional; | ||
| 73 | -import java.util.Properties; | ||
| 74 | -import java.util.Set; | ||
| 75 | -import java.util.concurrent.ConcurrentHashMap; | ||
| 76 | -import java.util.concurrent.ScheduledExecutorService; | ||
| 77 | 78 | ||
| 78 | import static com.google.common.base.Strings.isNullOrEmpty; | 79 | import static com.google.common.base.Strings.isNullOrEmpty; |
| 79 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | 80 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; |
| ... | @@ -141,6 +142,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -141,6 +142,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 141 | private LinkProviderService providerService; | 142 | private LinkProviderService providerService; |
| 142 | 143 | ||
| 143 | private ScheduledExecutorService executor; | 144 | private ScheduledExecutorService executor; |
| 145 | + protected ExecutorService eventExecutor; | ||
| 144 | 146 | ||
| 145 | private boolean shuttingDown = false; | 147 | private boolean shuttingDown = false; |
| 146 | 148 | ||
| ... | @@ -240,6 +242,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -240,6 +242,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 240 | 242 | ||
| 241 | @Activate | 243 | @Activate |
| 242 | public void activate(ComponentContext context) { | 244 | public void activate(ComponentContext context) { |
| 245 | + eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/linkevents", "events-%d", log)); | ||
| 243 | shuttingDown = false; | 246 | shuttingDown = false; |
| 244 | cfgService.registerProperties(getClass()); | 247 | cfgService.registerProperties(getClass()); |
| 245 | appId = coreService.registerApplication(PROVIDER_NAME); | 248 | appId = coreService.registerApplication(PROVIDER_NAME); |
| ... | @@ -274,6 +277,8 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -274,6 +277,8 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 274 | 277 | ||
| 275 | cfgService.unregisterProperties(getClass(), false); | 278 | cfgService.unregisterProperties(getClass(), false); |
| 276 | disable(); | 279 | disable(); |
| 280 | + eventExecutor.shutdownNow(); | ||
| 281 | + eventExecutor = null; | ||
| 277 | log.info("Stopped"); | 282 | log.info("Stopped"); |
| 278 | } | 283 | } |
| 279 | 284 | ||
| ... | @@ -542,27 +547,30 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -542,27 +547,30 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 542 | return; | 547 | return; |
| 543 | } | 548 | } |
| 544 | 549 | ||
| 545 | - DeviceId deviceId = event.subject(); | 550 | + eventExecutor.execute(() -> { |
| 546 | - Device device = deviceService.getDevice(deviceId); | 551 | + DeviceId deviceId = event.subject(); |
| 547 | - if (device == null) { | 552 | + Device device = deviceService.getDevice(deviceId); |
| 548 | - log.debug("Device {} doesn't exist, or isn't there yet", deviceId); | 553 | + if (device == null) { |
| 549 | - return; | 554 | + log.debug("Device {} doesn't exist, or isn't there yet", deviceId); |
| 550 | - } | 555 | + return; |
| 551 | - if (clusterService.getLocalNode().id().equals(event.roleInfo().master())) { | 556 | + } |
| 552 | - updateDevice(device).ifPresent(ld -> updatePorts(ld, device.id())); | 557 | + if (clusterService.getLocalNode().id().equals(event.roleInfo().master())) { |
| 553 | - } | 558 | + updateDevice(device).ifPresent(ld -> updatePorts(ld, device.id())); |
| 559 | + } | ||
| 560 | + }); | ||
| 554 | } | 561 | } |
| 555 | } | 562 | } |
| 556 | 563 | ||
| 557 | - /** | 564 | + private class DeviceEventProcessor implements Runnable { |
| 558 | - * Processes device events. | 565 | + |
| 559 | - */ | 566 | + DeviceEvent event; |
| 560 | - private class InternalDeviceListener implements DeviceListener { | 567 | + |
| 568 | + DeviceEventProcessor(DeviceEvent event) { | ||
| 569 | + this.event = event; | ||
| 570 | + } | ||
| 571 | + | ||
| 561 | @Override | 572 | @Override |
| 562 | - public void event(DeviceEvent event) { | 573 | + public void run() { |
| 563 | - if (event.type() == Type.PORT_STATS_UPDATED) { | ||
| 564 | - return; | ||
| 565 | - } | ||
| 566 | Device device = event.subject(); | 574 | Device device = event.subject(); |
| 567 | Port port = event.port(); | 575 | Port port = event.port(); |
| 568 | if (device == null) { | 576 | if (device == null) { |
| ... | @@ -618,6 +626,22 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -618,6 +626,22 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 618 | } | 626 | } |
| 619 | 627 | ||
| 620 | /** | 628 | /** |
| 629 | + * Processes device events. | ||
| 630 | + */ | ||
| 631 | + private class InternalDeviceListener implements DeviceListener { | ||
| 632 | + @Override | ||
| 633 | + public void event(DeviceEvent event) { | ||
| 634 | + if (event.type() == Type.PORT_STATS_UPDATED) { | ||
| 635 | + return; | ||
| 636 | + } | ||
| 637 | + | ||
| 638 | + Runnable deviceEventProcessor = new DeviceEventProcessor(event); | ||
| 639 | + | ||
| 640 | + eventExecutor.execute(deviceEventProcessor); | ||
| 641 | + } | ||
| 642 | + } | ||
| 643 | + | ||
| 644 | + /** | ||
| 621 | * Processes incoming packets. | 645 | * Processes incoming packets. |
| 622 | */ | 646 | */ |
| 623 | private class InternalPacketProcessor implements PacketProcessor { | 647 | private class InternalPacketProcessor implements PacketProcessor { |
| ... | @@ -774,7 +798,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -774,7 +798,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 774 | 798 | ||
| 775 | @Override | 799 | @Override |
| 776 | public void event(NetworkConfigEvent event) { | 800 | public void event(NetworkConfigEvent event) { |
| 777 | - SharedExecutors.getPoolThreadExecutor().execute(() -> { | 801 | + eventExecutor.execute(() -> { |
| 778 | if (event.configClass() == LinkDiscoveryFromDevice.class && | 802 | if (event.configClass() == LinkDiscoveryFromDevice.class && |
| 779 | CONFIG_CHANGED.contains(event.type())) { | 803 | CONFIG_CHANGED.contains(event.type())) { |
| 780 | 804 | ... | ... |
| ... | @@ -15,11 +15,15 @@ | ... | @@ -15,11 +15,15 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.provider.lldp.impl; | 16 | package org.onosproject.provider.lldp.impl; |
| 17 | 17 | ||
| 18 | -import com.google.common.collect.ArrayListMultimap; | 18 | +import java.nio.ByteBuffer; |
| 19 | -import com.google.common.collect.ImmutableList; | 19 | +import java.util.Collections; |
| 20 | -import com.google.common.collect.ImmutableMap; | 20 | +import java.util.HashMap; |
| 21 | -import com.google.common.collect.ImmutableSet; | 21 | +import java.util.HashSet; |
| 22 | -import com.google.common.collect.Lists; | 22 | +import java.util.List; |
| 23 | +import java.util.Map; | ||
| 24 | +import java.util.Set; | ||
| 25 | +import java.util.concurrent.CompletableFuture; | ||
| 26 | + | ||
| 23 | import org.junit.After; | 27 | import org.junit.After; |
| 24 | import org.junit.Before; | 28 | import org.junit.Before; |
| 25 | import org.junit.Test; | 29 | import org.junit.Test; |
| ... | @@ -66,14 +70,12 @@ import org.onosproject.net.packet.PacketServiceAdapter; | ... | @@ -66,14 +70,12 @@ import org.onosproject.net.packet.PacketServiceAdapter; |
| 66 | import org.onosproject.net.provider.ProviderId; | 70 | import org.onosproject.net.provider.ProviderId; |
| 67 | import org.onosproject.provider.lldpcommon.LinkDiscovery; | 71 | import org.onosproject.provider.lldpcommon.LinkDiscovery; |
| 68 | 72 | ||
| 69 | -import java.nio.ByteBuffer; | 73 | +import com.google.common.collect.ArrayListMultimap; |
| 70 | -import java.util.Collections; | 74 | +import com.google.common.collect.ImmutableList; |
| 71 | -import java.util.HashMap; | 75 | +import com.google.common.collect.ImmutableMap; |
| 72 | -import java.util.HashSet; | 76 | +import com.google.common.collect.ImmutableSet; |
| 73 | -import java.util.List; | 77 | +import com.google.common.collect.Lists; |
| 74 | -import java.util.Map; | 78 | +import com.google.common.util.concurrent.MoreExecutors; |
| 75 | -import java.util.Set; | ||
| 76 | -import java.util.concurrent.CompletableFuture; | ||
| 77 | 79 | ||
| 78 | import static org.easymock.EasyMock.createMock; | 80 | import static org.easymock.EasyMock.createMock; |
| 79 | import static org.easymock.EasyMock.expect; | 81 | import static org.easymock.EasyMock.expect; |
| ... | @@ -146,6 +148,8 @@ public class LldpLinkProviderTest { | ... | @@ -146,6 +148,8 @@ public class LldpLinkProviderTest { |
| 146 | 148 | ||
| 147 | provider.activate(null); | 149 | provider.activate(null); |
| 148 | 150 | ||
| 151 | + provider.eventExecutor = MoreExecutors.newDirectExecutorService(); | ||
| 152 | + | ||
| 149 | providerService = linkRegistry.registeredProvider(); | 153 | providerService = linkRegistry.registeredProvider(); |
| 150 | } | 154 | } |
| 151 | 155 | ... | ... |
| ... | @@ -255,6 +255,9 @@ public class LinkDiscovery implements TimerTask { | ... | @@ -255,6 +255,9 @@ public class LinkDiscovery implements TimerTask { |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | private void sendProbes(Long portNumber) { | 257 | private void sendProbes(Long portNumber) { |
| 258 | + if (context.packetService() == null) { | ||
| 259 | + return; | ||
| 260 | + } | ||
| 258 | log.trace("Sending probes out to {}@{}", portNumber, device.id()); | 261 | log.trace("Sending probes out to {}@{}", portNumber, device.id()); |
| 259 | OutboundPacket pkt = createOutBoundLldp(portNumber); | 262 | OutboundPacket pkt = createOutBoundLldp(portNumber); |
| 260 | context.packetService().emit(pkt); | 263 | context.packetService().emit(pkt); | ... | ... |
-
Please register or login to post a comment