Fix ONOS-4683 - Don't process device events on the listener thread
Change-Id: Icc465311c2c047dba11bacc69c745bbda55ea714
Showing
3 changed files
with
62 additions
and
32 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.onlab.util.Tools; | 36 | import org.onlab.util.Tools; |
| 31 | import org.onosproject.cfg.ComponentConfigService; | 37 | import org.onosproject.cfg.ComponentConfigService; |
| 32 | import org.onosproject.cluster.ClusterMetadataService; | 38 | import org.onosproject.cluster.ClusterMetadataService; |
| ... | @@ -52,30 +58,25 @@ import org.onosproject.net.device.DeviceService; | ... | @@ -52,30 +58,25 @@ import org.onosproject.net.device.DeviceService; |
| 52 | import org.onosproject.net.flow.DefaultTrafficSelector; | 58 | import org.onosproject.net.flow.DefaultTrafficSelector; |
| 53 | import org.onosproject.net.flow.TrafficSelector; | 59 | import org.onosproject.net.flow.TrafficSelector; |
| 54 | import org.onosproject.net.link.DefaultLinkDescription; | 60 | import org.onosproject.net.link.DefaultLinkDescription; |
| 55 | -import org.onosproject.net.link.ProbedLinkProvider; | ||
| 56 | import org.onosproject.net.link.LinkProviderRegistry; | 61 | import org.onosproject.net.link.LinkProviderRegistry; |
| 57 | import org.onosproject.net.link.LinkProviderService; | 62 | import org.onosproject.net.link.LinkProviderService; |
| 58 | import org.onosproject.net.link.LinkService; | 63 | import org.onosproject.net.link.LinkService; |
| 64 | +import org.onosproject.net.link.ProbedLinkProvider; | ||
| 59 | import org.onosproject.net.packet.PacketContext; | 65 | import org.onosproject.net.packet.PacketContext; |
| 60 | import org.onosproject.net.packet.PacketPriority; | 66 | import org.onosproject.net.packet.PacketPriority; |
| 61 | import org.onosproject.net.packet.PacketProcessor; | 67 | import org.onosproject.net.packet.PacketProcessor; |
| 62 | import org.onosproject.net.packet.PacketService; | 68 | import org.onosproject.net.packet.PacketService; |
| 63 | import org.onosproject.net.provider.AbstractProvider; | 69 | import org.onosproject.net.provider.AbstractProvider; |
| 64 | import org.onosproject.net.provider.ProviderId; | 70 | import org.onosproject.net.provider.ProviderId; |
| 65 | -import org.onosproject.provider.lldpcommon.LinkDiscoveryContext; | ||
| 66 | import org.onosproject.provider.lldpcommon.LinkDiscovery; | 71 | import org.onosproject.provider.lldpcommon.LinkDiscovery; |
| 72 | +import org.onosproject.provider.lldpcommon.LinkDiscoveryContext; | ||
| 67 | import org.onosproject.store.service.ConsistentMapException; | 73 | import org.onosproject.store.service.ConsistentMapException; |
| 68 | import org.osgi.service.component.ComponentContext; | 74 | import org.osgi.service.component.ComponentContext; |
| 69 | import org.slf4j.Logger; | 75 | import org.slf4j.Logger; |
| 70 | 76 | ||
| 71 | -import java.util.Dictionary; | 77 | +import com.google.common.collect.ImmutableMap; |
| 72 | -import java.util.EnumSet; | 78 | +import com.google.common.collect.ImmutableSet; |
| 73 | -import java.util.Map; | 79 | +import com.google.common.collect.Maps; |
| 74 | -import java.util.Optional; | ||
| 75 | -import java.util.Properties; | ||
| 76 | -import java.util.Set; | ||
| 77 | -import java.util.concurrent.ConcurrentHashMap; | ||
| 78 | -import java.util.concurrent.ScheduledExecutorService; | ||
| 79 | 80 | ||
| 80 | import static com.google.common.base.Strings.isNullOrEmpty; | 81 | import static com.google.common.base.Strings.isNullOrEmpty; |
| 81 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | 82 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; |
| ... | @@ -143,6 +144,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -143,6 +144,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 143 | private LinkProviderService providerService; | 144 | private LinkProviderService providerService; |
| 144 | 145 | ||
| 145 | private ScheduledExecutorService executor; | 146 | private ScheduledExecutorService executor; |
| 147 | + protected ExecutorService eventExecutor; | ||
| 146 | 148 | ||
| 147 | private boolean shuttingDown = false; | 149 | private boolean shuttingDown = false; |
| 148 | 150 | ||
| ... | @@ -242,6 +244,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -242,6 +244,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 242 | 244 | ||
| 243 | @Activate | 245 | @Activate |
| 244 | public void activate(ComponentContext context) { | 246 | public void activate(ComponentContext context) { |
| 247 | + eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/linkevents", "events-%d", log)); | ||
| 245 | shuttingDown = false; | 248 | shuttingDown = false; |
| 246 | cfgService.registerProperties(getClass()); | 249 | cfgService.registerProperties(getClass()); |
| 247 | appId = coreService.registerApplication(PROVIDER_NAME); | 250 | appId = coreService.registerApplication(PROVIDER_NAME); |
| ... | @@ -280,6 +283,8 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -280,6 +283,8 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 280 | 283 | ||
| 281 | cfgService.unregisterProperties(getClass(), false); | 284 | cfgService.unregisterProperties(getClass(), false); |
| 282 | disable(); | 285 | disable(); |
| 286 | + eventExecutor.shutdownNow(); | ||
| 287 | + eventExecutor = null; | ||
| 283 | log.info("Stopped"); | 288 | log.info("Stopped"); |
| 284 | } | 289 | } |
| 285 | 290 | ||
| ... | @@ -548,27 +553,30 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -548,27 +553,30 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 548 | return; | 553 | return; |
| 549 | } | 554 | } |
| 550 | 555 | ||
| 551 | - DeviceId deviceId = event.subject(); | 556 | + eventExecutor.execute(() -> { |
| 552 | - Device device = deviceService.getDevice(deviceId); | 557 | + DeviceId deviceId = event.subject(); |
| 553 | - if (device == null) { | 558 | + Device device = deviceService.getDevice(deviceId); |
| 554 | - log.debug("Device {} doesn't exist, or isn't there yet", deviceId); | 559 | + if (device == null) { |
| 555 | - return; | 560 | + log.debug("Device {} doesn't exist, or isn't there yet", deviceId); |
| 556 | - } | 561 | + return; |
| 557 | - if (clusterService.getLocalNode().id().equals(event.roleInfo().master())) { | 562 | + } |
| 558 | - updateDevice(device).ifPresent(ld -> updatePorts(ld, device.id())); | 563 | + if (clusterService.getLocalNode().id().equals(event.roleInfo().master())) { |
| 559 | - } | 564 | + updateDevice(device).ifPresent(ld -> updatePorts(ld, device.id())); |
| 565 | + } | ||
| 566 | + }); | ||
| 560 | } | 567 | } |
| 561 | } | 568 | } |
| 562 | 569 | ||
| 563 | - /** | 570 | + private class DeviceEventProcessor implements Runnable { |
| 564 | - * Processes device events. | 571 | + |
| 565 | - */ | 572 | + DeviceEvent event; |
| 566 | - private class InternalDeviceListener implements DeviceListener { | 573 | + |
| 574 | + DeviceEventProcessor(DeviceEvent event) { | ||
| 575 | + this.event = event; | ||
| 576 | + } | ||
| 577 | + | ||
| 567 | @Override | 578 | @Override |
| 568 | - public void event(DeviceEvent event) { | 579 | + public void run() { |
| 569 | - if (event.type() == Type.PORT_STATS_UPDATED) { | ||
| 570 | - return; | ||
| 571 | - } | ||
| 572 | Device device = event.subject(); | 580 | Device device = event.subject(); |
| 573 | Port port = event.port(); | 581 | Port port = event.port(); |
| 574 | if (device == null) { | 582 | if (device == null) { |
| ... | @@ -624,6 +632,22 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -624,6 +632,22 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 624 | } | 632 | } |
| 625 | 633 | ||
| 626 | /** | 634 | /** |
| 635 | + * Processes device events. | ||
| 636 | + */ | ||
| 637 | + private class InternalDeviceListener implements DeviceListener { | ||
| 638 | + @Override | ||
| 639 | + public void event(DeviceEvent event) { | ||
| 640 | + if (event.type() == Type.PORT_STATS_UPDATED) { | ||
| 641 | + return; | ||
| 642 | + } | ||
| 643 | + | ||
| 644 | + Runnable deviceEventProcessor = new DeviceEventProcessor(event); | ||
| 645 | + | ||
| 646 | + eventExecutor.execute(deviceEventProcessor); | ||
| 647 | + } | ||
| 648 | + } | ||
| 649 | + | ||
| 650 | + /** | ||
| 627 | * Processes incoming packets. | 651 | * Processes incoming packets. |
| 628 | */ | 652 | */ |
| 629 | private class InternalPacketProcessor implements PacketProcessor { | 653 | private class InternalPacketProcessor implements PacketProcessor { |
| ... | @@ -780,7 +804,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv | ... | @@ -780,7 +804,7 @@ public class LldpLinkProvider extends AbstractProvider implements ProbedLinkProv |
| 780 | 804 | ||
| 781 | @Override | 805 | @Override |
| 782 | public void event(NetworkConfigEvent event) { | 806 | public void event(NetworkConfigEvent event) { |
| 783 | - SharedExecutors.getPoolThreadExecutor().execute(() -> { | 807 | + eventExecutor.execute(() -> { |
| 784 | if (event.configClass() == LinkDiscoveryFromDevice.class && | 808 | if (event.configClass() == LinkDiscoveryFromDevice.class && |
| 785 | CONFIG_CHANGED.contains(event.type())) { | 809 | CONFIG_CHANGED.contains(event.type())) { |
| 786 | 810 | ... | ... |
| ... | @@ -75,6 +75,7 @@ import com.google.common.collect.ImmutableList; | ... | @@ -75,6 +75,7 @@ import com.google.common.collect.ImmutableList; |
| 75 | import com.google.common.collect.ImmutableMap; | 75 | import com.google.common.collect.ImmutableMap; |
| 76 | import com.google.common.collect.ImmutableSet; | 76 | import com.google.common.collect.ImmutableSet; |
| 77 | import com.google.common.collect.Lists; | 77 | import com.google.common.collect.Lists; |
| 78 | +import com.google.common.util.concurrent.MoreExecutors; | ||
| 78 | 79 | ||
| 79 | import static org.easymock.EasyMock.createMock; | 80 | import static org.easymock.EasyMock.createMock; |
| 80 | import static org.easymock.EasyMock.expect; | 81 | import static org.easymock.EasyMock.expect; |
| ... | @@ -147,6 +148,8 @@ public class LldpLinkProviderTest { | ... | @@ -147,6 +148,8 @@ public class LldpLinkProviderTest { |
| 147 | 148 | ||
| 148 | provider.activate(null); | 149 | provider.activate(null); |
| 149 | 150 | ||
| 151 | + provider.eventExecutor = MoreExecutors.newDirectExecutorService(); | ||
| 152 | + | ||
| 150 | providerService = linkRegistry.registeredProvider(); | 153 | providerService = linkRegistry.registeredProvider(); |
| 151 | } | 154 | } |
| 152 | 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