From: Robert Varga Date: Fri, 14 Nov 2014 11:53:17 +0000 (+0100) Subject: Do not retain NetconfConnectModule reference X-Git-Tag: release/lithium~868^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=02541f9e4c26b77e9e592f68b103cb71cf99017b Do not retain NetconfConnectModule reference Anononymous classes retain a reference to the module, which means we leak quite a bit of memory if the client is not shut down. Change-Id: Ifeaeb383afe8ff5c899cee66ea861e30bdf2ae41 Signed-off-by: Robert Varga --- diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java index bca47af5c0..97e294016d 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java @@ -9,8 +9,9 @@ package org.opendaylight.controller.config.yang.md.sal.connector.netconf; import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkCondition; import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkNotNull; - import com.google.common.base.Optional; +import io.netty.util.concurrent.EventExecutor; +import java.math.BigDecimal; import java.net.InetSocketAddress; import java.util.List; import java.util.concurrent.ExecutorService; @@ -120,13 +121,7 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co final NetconfClientDispatcher dispatcher = getClientDispatcherDependency(); listener.initializeRemoteConnection(dispatcher, clientConfig); - return new AutoCloseable() { - @Override - public void close() throws Exception { - listener.close(); - salFacade.close(); - } - }; + return new MyAutoCloseable(listener, salFacade); } private Optional getUserCapabilities() { @@ -155,9 +150,12 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co public NetconfReconnectingClientConfiguration getClientConfig(final NetconfDeviceCommunicator listener) { final InetSocketAddress socketAddress = getSocketAddress(); - final ReconnectStrategy strategy = getReconnectStrategy(); final long clientConnectionTimeoutMillis = getConnectionTimeoutMillis(); + final ReconnectStrategyFactory sf = new MyReconnectStrategyFactory( + getEventExecutorDependency(), getMaxConnectionAttempts(), getBetweenAttemptsTimeoutMillis(), getSleepFactor()); + final ReconnectStrategy strategy = sf.createReconnectStrategy(); + return NetconfReconnectingClientConfigurationBuilder.create() .withAddress(socketAddress) .withConnectionTimeoutMillis(clientConnectionTimeoutMillis) @@ -167,30 +165,54 @@ public final class NetconfConnectorModule extends org.opendaylight.controller.co .withProtocol(getTcpOnly() ? NetconfClientConfiguration.NetconfClientProtocol.TCP : NetconfClientConfiguration.NetconfClientProtocol.SSH) - .withConnectStrategyFactory(new ReconnectStrategyFactory() { - @Override - public ReconnectStrategy createReconnectStrategy() { - return getReconnectStrategy(); - } - }) + .withConnectStrategyFactory(sf) .build(); } - private ReconnectStrategy getReconnectStrategy() { - final Long connectionAttempts; - if (getMaxConnectionAttempts() != null && getMaxConnectionAttempts() > 0) { - connectionAttempts = getMaxConnectionAttempts(); - } else { - logger.trace("Setting {} on {} to infinity", maxConnectionAttemptsJmxAttribute, this); - connectionAttempts = null; + private static final class MyAutoCloseable implements AutoCloseable { + private final RemoteDeviceHandler salFacade; + private final NetconfDeviceCommunicator listener; + + public MyAutoCloseable(final NetconfDeviceCommunicator listener, + final RemoteDeviceHandler salFacade) { + this.listener = listener; + this.salFacade = salFacade; } - final double sleepFactor = getSleepFactor().doubleValue(); - final int minSleep = getBetweenAttemptsTimeoutMillis(); - final Long maxSleep = null; - final Long deadline = null; - return new TimedReconnectStrategy(getEventExecutorDependency(), getBetweenAttemptsTimeoutMillis(), - minSleep, sleepFactor, maxSleep, connectionAttempts, deadline); + @Override + public void close() { + listener.close(); + salFacade.close(); + } + } + + private static final class MyReconnectStrategyFactory implements ReconnectStrategyFactory { + private final Long connectionAttempts; + private final EventExecutor executor; + private final double sleepFactor; + private final int minSleep; + + MyReconnectStrategyFactory(final EventExecutor executor, final Long maxConnectionAttempts, final int minSleep, final BigDecimal sleepFactor) { + if (maxConnectionAttempts != null && maxConnectionAttempts > 0) { + connectionAttempts = maxConnectionAttempts; + } else { + logger.trace("Setting {} on {} to infinity", maxConnectionAttemptsJmxAttribute, this); + connectionAttempts = null; + } + + this.sleepFactor = sleepFactor.doubleValue(); + this.executor = executor; + this.minSleep = minSleep; + } + + @Override + public ReconnectStrategy createReconnectStrategy() { + final Long maxSleep = null; + final Long deadline = null; + + return new TimedReconnectStrategy(executor, minSleep, + minSleep, sleepFactor, maxSleep, connectionAttempts, deadline); + } } private InetSocketAddress getSocketAddress() {