From f87c8b6ee4275825ba7b3bd3c706be9e95f480f4 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 26 Jan 2024 01:48:52 +0100 Subject: [PATCH] Eliminate GlobalNetconfSshScheduledExecutor The only thing this executor is used is for ietf-monitoring listener updates for netconf-server. Rather than having a tuneable threadpool, just acknowledge the fact we need a single thread for this task and manage it internally NetconfMonitoringServiceImpl if possible. JIRA: NETCONF-1232 Change-Id: I081947c28981442777ea8bc91a77df01641d23fe Signed-off-by: Robert Varga --- .../DefaultNetconfMonitoringService.java | 20 +++--- .../netconf/northbound/OSGiNetconfServer.java | 6 +- .../netconf/config/Configuration.java | 3 - .../config/GlobalNetconfConfiguration.java | 19 ------ .../GlobalNetconfSshScheduledExecutor.java | 62 ------------------- .../config/GlobalNetconfThreadFactory.java | 3 +- .../osgi/NetconfMonitoringServiceImpl.java | 21 +++++++ 7 files changed, 36 insertions(+), 98 deletions(-) delete mode 100644 netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfSshScheduledExecutor.java diff --git a/apps/netconf-nb/src/main/java/org/opendaylight/netconf/northbound/DefaultNetconfMonitoringService.java b/apps/netconf-nb/src/main/java/org/opendaylight/netconf/northbound/DefaultNetconfMonitoringService.java index b4af03671b..787e8aad99 100644 --- a/apps/netconf-nb/src/main/java/org/opendaylight/netconf/northbound/DefaultNetconfMonitoringService.java +++ b/apps/netconf-nb/src/main/java/org/opendaylight/netconf/northbound/DefaultNetconfMonitoringService.java @@ -9,8 +9,10 @@ package org.opendaylight.netconf.northbound; import static java.util.Objects.requireNonNull; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.util.Map; -import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; import org.opendaylight.netconf.server.api.monitoring.NetconfMonitoringService; import org.opendaylight.netconf.server.api.operations.NetconfOperationServiceFactory; import org.opendaylight.netconf.server.osgi.NetconfMonitoringServiceImpl; @@ -22,14 +24,20 @@ import org.osgi.service.component.annotations.Deactivate; public final class DefaultNetconfMonitoringService extends NetconfMonitoringServiceImpl { static final String FACTORY_NAME = "org.opendaylight.netconf.impl.mdsal.DefaultNetconfMonitoringService"; + private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder() + .setNameFormat("netconf-server-monitoring-%d") + .setDaemon(true) + .build(); private static final String OP_PROVIDER_PROP = ".opProvider"; - private static final String THREAD_POOL_PROP = ".threadPool"; private static final String UPDATE_INTERVAL_PROP = ".updateInterval"; + private DefaultNetconfMonitoringService(final NetconfOperationServiceFactory opProvider, final long periodSeconds) { + super(opProvider, THREAD_FACTORY, periodSeconds, TimeUnit.SECONDS); + } + @Activate public DefaultNetconfMonitoringService(final Map properties) { - super(OSGiNetconfServer.extractProp(properties, OP_PROVIDER_PROP, NetconfOperationServiceFactory.class), - OSGiNetconfServer.extractProp(properties, THREAD_POOL_PROP, ScheduledExecutorService.class), + this(OSGiNetconfServer.extractProp(properties, OP_PROVIDER_PROP, NetconfOperationServiceFactory.class), OSGiNetconfServer.extractProp(properties, UPDATE_INTERVAL_PROP, Long.class)); } @@ -39,12 +47,10 @@ public final class DefaultNetconfMonitoringService extends NetconfMonitoringServ super.close(); } - static Map props(final NetconfOperationServiceFactory opProvider, - final ScheduledExecutorService threadPool, final long updateInterval) { + static Map props(final NetconfOperationServiceFactory opProvider, final long updateInterval) { return Map.of( "type", "netconf-server-monitoring", OP_PROVIDER_PROP, requireNonNull(opProvider), - THREAD_POOL_PROP, requireNonNull(threadPool), UPDATE_INTERVAL_PROP, updateInterval); } } diff --git a/apps/netconf-nb/src/main/java/org/opendaylight/netconf/northbound/OSGiNetconfServer.java b/apps/netconf-nb/src/main/java/org/opendaylight/netconf/northbound/OSGiNetconfServer.java index 6f193cf3f1..ee6271593e 100644 --- a/apps/netconf-nb/src/main/java/org/opendaylight/netconf/northbound/OSGiNetconfServer.java +++ b/apps/netconf-nb/src/main/java/org/opendaylight/netconf/northbound/OSGiNetconfServer.java @@ -12,7 +12,6 @@ import static java.util.Objects.requireNonNull; import io.netty.util.Timer; import java.util.Map; -import org.opendaylight.controller.config.threadpool.ScheduledThreadPool; import org.opendaylight.netconf.server.NetconfServerSessionNegotiatorFactory; import org.opendaylight.netconf.server.ServerTransportInitializer; import org.opendaylight.netconf.server.api.SessionIdProvider; @@ -50,15 +49,12 @@ public final class OSGiNetconfServer { final ComponentFactory monitoringFactory, @Reference(target = "(type=mapper-aggregator-registry)") final NetconfOperationServiceFactory mapperAggregatorRegistry, - @Reference(target = "(type=global-netconf-ssh-scheduled-executor)") - final ScheduledThreadPool sshScheduledExecutor, @Reference(target = "(type=global-timer)") final Timer timer, @Reference final SessionIdProvider sessionIdProvider, final Configuration configuration) { mappers.onAddNetconfOperationServiceFactory(mapperAggregatorRegistry); monitoring = monitoringFactory.newInstance(FrameworkUtil.asDictionary(DefaultNetconfMonitoringService.props( - mapperAggregatorRegistry, sshScheduledExecutor.getExecutor(), - configuration.monitoring$_$update$_$interval()))); + mapperAggregatorRegistry, configuration.monitoring$_$update$_$interval()))); serverTransportInitializer = new ServerTransportInitializer(NetconfServerSessionNegotiatorFactory.builder() .setTimer(timer) .setAggregatedOpService(mappers) diff --git a/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/Configuration.java b/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/Configuration.java index fbe7be79ee..144fac3550 100644 --- a/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/Configuration.java +++ b/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/Configuration.java @@ -25,7 +25,4 @@ public @interface Configuration { @AttributeDefinition(min = "0") long keep$_$alive$_$millis$_$flexible$_$thread$_$pool() default GlobalNetconfProcessingExecutor.DEFAULT_KEEPALIVE_MILLIS; - @AttributeDefinition(min = "1") - int max$_$thread$_$count$_$scheduled$_$thread$_$pool() - default GlobalNetconfSshScheduledExecutor.DEFAULT_MAX_THREAD_COUNT; } diff --git a/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfConfiguration.java b/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfConfiguration.java index 0d0bfd4dd5..de2c608bbf 100644 --- a/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfConfiguration.java +++ b/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfConfiguration.java @@ -33,29 +33,21 @@ public final class GlobalNetconfConfiguration { private static final Logger LOG = LoggerFactory.getLogger(GlobalNetconfConfiguration.class); private final ComponentFactory processingFactory; - private final ComponentFactory sshScheduledFactory; private GlobalNetconfThreadFactory threadFactory; private ComponentInstance processingExecutor; private Map processingProps; - private ComponentInstance sshScheduledExecutor; - private Map sshScheduledProps; @Activate public GlobalNetconfConfiguration( @Reference(target = "(component.factory=" + GlobalNetconfProcessingExecutor.FACTORY_NAME + ")") final ComponentFactory processingFactory, - @Reference(target = "(component.factory=" + GlobalNetconfSshScheduledExecutor.FACTORY_NAME + ")") - final ComponentFactory sshScheduledFactory, final Configuration configuration) { this.processingFactory = requireNonNull(processingFactory); - this.sshScheduledFactory = requireNonNull(sshScheduledFactory); threadFactory = new GlobalNetconfThreadFactory(configuration.name$_$prefix()); processingProps = GlobalNetconfProcessingExecutor.props(threadFactory, configuration); processingExecutor = processingFactory.newInstance(FrameworkUtil.asDictionary(processingProps)); - sshScheduledProps = GlobalNetconfSshScheduledExecutor.props(threadFactory, configuration); - sshScheduledExecutor = sshScheduledFactory.newInstance(FrameworkUtil.asDictionary(sshScheduledProps)); LOG.info("Global NETCONF configuration pools started"); } @@ -65,7 +57,6 @@ public final class GlobalNetconfConfiguration { if (!threadFactory.getNamePrefix().equals(newNamePrefix)) { threadFactory = new GlobalNetconfThreadFactory(newNamePrefix); processingProps = null; - sshScheduledProps = null; LOG.debug("Forcing restart of all executors"); } @@ -80,14 +71,6 @@ public final class GlobalNetconfConfiguration { LOG.debug("Processing executor restarted with {}", processingProps); } - final var newSshScheduledProps = GlobalNetconfSshScheduledExecutor.props(threadFactory, configuration); - if (!newSshScheduledProps.equals(sshScheduledProps)) { - sshScheduledProps = newSshScheduledProps; - toDispose.add(sshScheduledExecutor); - sshScheduledExecutor = sshScheduledFactory.newInstance(FrameworkUtil.asDictionary(sshScheduledProps)); - LOG.debug("Scheduled executor restarted with {}", sshScheduledProps); - } - toDispose.forEach(ComponentInstance::dispose); } @@ -95,8 +78,6 @@ public final class GlobalNetconfConfiguration { void deactivate() { processingExecutor.dispose(); processingExecutor = null; - sshScheduledExecutor.dispose(); - sshScheduledExecutor = null; threadFactory = null; LOG.info("Global NETCONF configuration pools stopped"); } diff --git a/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfSshScheduledExecutor.java b/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfSshScheduledExecutor.java deleted file mode 100644 index 29e0bfc0d6..0000000000 --- a/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfSshScheduledExecutor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.netconf.config; - -import static java.util.Objects.requireNonNull; - -import java.util.Map; -import javax.annotation.PreDestroy; -import javax.inject.Inject; -import javax.inject.Singleton; -import org.opendaylight.controller.config.threadpool.ScheduledThreadPool; -import org.opendaylight.controller.config.threadpool.util.ScheduledThreadPoolWrapper; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Deactivate; - -@Singleton -@Component(factory = GlobalNetconfSshScheduledExecutor.FACTORY_NAME, service = ScheduledThreadPool.class) -public final class GlobalNetconfSshScheduledExecutor extends ScheduledThreadPoolWrapper { - public static final String OSGI_TYPE = "global-netconf-ssh-scheduled-executor"; - public static final int DEFAULT_MAX_THREAD_COUNT = 8; - - // OSGi DS Component Factory name - static final String FACTORY_NAME = "org.opendaylight.netconf.config.GlobalNetconfSshScheduledExecutor"; - - private static final String PROP_MAX_THREAD_COUNT = ".maxThreadCount"; - private static final String PROP_THREAD_FACTORY = ".threadFactory"; - - public GlobalNetconfSshScheduledExecutor(final GlobalNetconfThreadFactory threadFactory, final int maxThreadCount) { - super(maxThreadCount, threadFactory); - } - - @Inject - public GlobalNetconfSshScheduledExecutor(final GlobalNetconfThreadFactory threadFactory) { - this(threadFactory, DEFAULT_MAX_THREAD_COUNT); - } - - @Activate - public GlobalNetconfSshScheduledExecutor(final Map properties) { - this(GlobalNetconfConfiguration.extractProp(properties, PROP_THREAD_FACTORY, GlobalNetconfThreadFactory.class), - GlobalNetconfConfiguration.extractProp(properties, PROP_MAX_THREAD_COUNT, Integer.class)); - } - - @Override - @PreDestroy - @Deactivate - public void close() { - super.close(); - } - - static Map props(final GlobalNetconfThreadFactory threadFactory, final Configuration configuration) { - return Map.of( - "type", OSGI_TYPE, - PROP_MAX_THREAD_COUNT, configuration.max$_$thread$_$count$_$scheduled$_$thread$_$pool(), - PROP_THREAD_FACTORY, requireNonNull(threadFactory)); - } -} diff --git a/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfThreadFactory.java b/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfThreadFactory.java index 1c06140ced..4cf4672781 100644 --- a/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfThreadFactory.java +++ b/netconf/netconf-config/src/main/java/org/opendaylight/netconf/config/GlobalNetconfThreadFactory.java @@ -12,8 +12,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.opendaylight.controller.config.threadpool.util.NamingThreadPoolFactory; /** - * Shared {@link NamingThreadPoolFactory} for {@link GlobalNetconfProcessingExecutor} and - * {@link GlobalNetconfSshScheduledExecutor}. + * Shared {@link NamingThreadPoolFactory} for {@link GlobalNetconfProcessingExecutor}. */ @NonNullByDefault public final class GlobalNetconfThreadFactory extends NamingThreadPoolFactory { diff --git a/protocol/netconf-server/src/main/java/org/opendaylight/netconf/server/osgi/NetconfMonitoringServiceImpl.java b/protocol/netconf-server/src/main/java/org/opendaylight/netconf/server/osgi/NetconfMonitoringServiceImpl.java index e0bddc7822..8fb2c53f20 100644 --- a/protocol/netconf-server/src/main/java/org/opendaylight/netconf/server/osgi/NetconfMonitoringServiceImpl.java +++ b/protocol/netconf-server/src/main/java/org/opendaylight/netconf/server/osgi/NetconfMonitoringServiceImpl.java @@ -10,7 +10,9 @@ package org.opendaylight.netconf.server.osgi; import static java.util.Objects.requireNonNull; import java.util.Optional; +import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import org.opendaylight.netconf.server.api.monitoring.NetconfMonitoringService; import org.opendaylight.netconf.server.api.monitoring.SessionListener; @@ -24,17 +26,33 @@ import org.opendaylight.yangtools.concepts.Registration; public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, AutoCloseable { private final NetconfCapabilityMonitoringService capabilityMonitoring; private final NetconfSessionMonitoringService sessionMonitoring; + private final ScheduledExecutorService executorService; private NetconfMonitoringServiceImpl(final NetconfOperationServiceFactory opProvider, final NetconfSessionMonitoringService sessionMonitoring) { capabilityMonitoring = new NetconfCapabilityMonitoringService(opProvider); this.sessionMonitoring = requireNonNull(sessionMonitoring); + executorService = null; } public NetconfMonitoringServiceImpl(final NetconfOperationServiceFactory opProvider) { this(opProvider, new NetconfSessionMonitoringService.WithoutUpdates()); } + public NetconfMonitoringServiceImpl(final NetconfOperationServiceFactory opProvider, + final ThreadFactory threadFactory, final long period, final TimeUnit timeUnit) { + capabilityMonitoring = new NetconfCapabilityMonitoringService(opProvider); + if (period > 0) { + executorService = Executors.unconfigurableScheduledExecutorService( + // Note: 0 core pool size, as we want to shut the thread down when we do not have listeners + Executors.newScheduledThreadPool(0, threadFactory)); + sessionMonitoring = new NetconfSessionMonitoringService.WithUpdates(executorService, period, timeUnit); + } else { + executorService = null; + sessionMonitoring = new NetconfSessionMonitoringService.WithoutUpdates(); + } + } + public NetconfMonitoringServiceImpl(final NetconfOperationServiceFactory opProvider, final ScheduledExecutorService threadPool, final long periodSeconds) { this(opProvider, periodSeconds > 0 @@ -85,5 +103,8 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, A public void close() { capabilityMonitoring.close(); sessionMonitoring.close(); + if (executorService != null) { + executorService.shutdown(); + } } } -- 2.36.6