IGNITE-7287 Thin client: add configurable idle connection timeout This closes #3287
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1a939b0a Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1a939b0a Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1a939b0a Branch: refs/heads/ignite-zk Commit: 1a939b0ae002ea7d7661e42f1468212a91b71e9c Parents: 9d2bd45 Author: Pavel Tupitsyn <[email protected]> Authored: Wed Dec 27 11:17:29 2017 +0300 Committer: Pavel Tupitsyn <[email protected]> Committed: Wed Dec 27 11:17:29 2017 +0300 ---------------------------------------------------------------------- .../ClientConnectorConfiguration.java | 33 +++++++++++++++++++ .../odbc/ClientListenerNioListener.java | 5 +++ .../odbc/ClientListenerProcessor.java | 3 +- .../utils/PlatformConfigurationUtils.java | 4 ++- .../Client/ClientConnectionTest.cs | 34 ++++++++++++++++++++ .../Config/full-config.xml | 2 +- .../IgniteConfigurationSerializerTest.cs | 4 ++- .../IgniteConfigurationTest.cs | 1 + .../ClientConnectorConfiguration.cs | 17 ++++++++++ .../IgniteConfigurationSection.xsd | 5 +++ 10 files changed, 104 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/1a939b0a/modules/core/src/main/java/org/apache/ignite/configuration/ClientConnectorConfiguration.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/ClientConnectorConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/ClientConnectorConfiguration.java index 1c33a00..d2520d2 100644 --- a/modules/core/src/main/java/org/apache/ignite/configuration/ClientConnectorConfiguration.java +++ b/modules/core/src/main/java/org/apache/ignite/configuration/ClientConnectorConfiguration.java @@ -42,6 +42,9 @@ public class ClientConnectorConfiguration { /** Default size of thread pool. */ public static final int DFLT_THREAD_POOL_SIZE = IgniteConfiguration.DFLT_PUBLIC_THREAD_CNT; + /** Default idle timeout. */ + public static final int DFLT_IDLE_TIMEOUT = 0; + /** Host. */ private String host; @@ -66,6 +69,9 @@ public class ClientConnectorConfiguration { /** Thread pool size. */ private int threadPoolSize = DFLT_THREAD_POOL_SIZE; + /** Idle timeout. */ + private long idleTimeout = DFLT_IDLE_TIMEOUT; + /** * Creates SQL connector configuration with all default values. */ @@ -89,6 +95,7 @@ public class ClientConnectorConfiguration { sockSndBufSize = cfg.getSocketSendBufferSize(); tcpNoDelay = cfg.isTcpNoDelay(); threadPoolSize = cfg.getThreadPoolSize(); + idleTimeout = cfg.getIdleTimeout(); } /** @@ -268,6 +275,32 @@ public class ClientConnectorConfiguration { return this; } + /** + * Gets idle timeout for client connections. + * If no packets come within idle timeout, the connection is closed. + * Zero or negative means no timeout. + * + * @return Idle timeout in milliseconds. + */ + public long getIdleTimeout() { + return idleTimeout; + } + + /** + * Sets idle timeout for client connections. + * If no packets come within idle timeout, the connection is closed. + * Zero or negative means no timeout. + * + * @param idleTimeout Idle timeout in milliseconds. + * @see #getIdleTimeout() + * @return {@code this} for chaining. + */ + public ClientConnectorConfiguration setIdleTimeout(long idleTimeout) { + this.idleTimeout = idleTimeout; + + return this; + } + /** {@inheritDoc} */ @Override public String toString() { return S.toString(ClientConnectorConfiguration.class, this); http://git-wip-us.apache.org/repos/asf/ignite/blob/1a939b0a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java index faecab3..b41e240 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerNioListener.java @@ -158,6 +158,11 @@ public class ClientListenerNioListener extends GridNioServerListenerAdapter<byte } } + /** {@inheritDoc} */ + @Override public void onSessionIdleTimeout(GridNioSession ses) { + ses.close(); + } + /** * Perform handshake. * http://git-wip-us.apache.org/repos/asf/ignite/blob/1a939b0a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerProcessor.java index 06977c8..ebd5156 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerProcessor.java @@ -123,6 +123,7 @@ public class ClientListenerProcessor extends GridProcessorAdapter { }; int maxOpenCursors = cliConnCfg.getMaxOpenCursorsPerConnection(); + long idleTimeout = cliConnCfg.getIdleTimeout(); GridNioServer<byte[]> srv0 = GridNioServer.<byte[]>builder() .address(hostAddr) @@ -139,7 +140,7 @@ public class ClientListenerProcessor extends GridProcessorAdapter { .socketReceiveBufferSize(cliConnCfg.getSocketReceiveBufferSize()) .filters(filters) .directMode(false) - .idleTimeout(Long.MAX_VALUE) + .idleTimeout(idleTimeout > 0 ? idleTimeout : Long.MAX_VALUE) .build(); srv0.start(); http://git-wip-us.apache.org/repos/asf/ignite/blob/1a939b0a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java index 6a265eb..b048f48 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java @@ -1589,7 +1589,8 @@ public class PlatformConfigurationUtils { .setSocketReceiveBufferSize(in.readInt()) .setTcpNoDelay(in.readBoolean()) .setMaxOpenCursorsPerConnection(in.readInt()) - .setThreadPoolSize(in.readInt()); + .setThreadPoolSize(in.readInt()) + .setIdleTimeout(in.readLong()); } /** @@ -1611,6 +1612,7 @@ public class PlatformConfigurationUtils { w.writeBoolean(cfg.isTcpNoDelay()); w.writeInt(cfg.getMaxOpenCursorsPerConnection()); w.writeInt(cfg.getThreadPoolSize()); + w.writeLong(cfg.getIdleTimeout()); } else { w.writeBoolean(false); } http://git-wip-us.apache.org/repos/asf/ignite/blob/1a939b0a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs index 2b92eb7..0bf3c37 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs @@ -272,6 +272,40 @@ namespace Apache.Ignite.Core.Tests.Client } /// <summary> + /// Tests the <see cref="ClientConnectorConfiguration.IdleTimeout"/> property. + /// </summary> + [Test] + [Category(TestUtils.CategoryIntensive)] + public void TestIdleTimeout() + { + var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration()) + { + ClientConnectorConfiguration = new ClientConnectorConfiguration + { + IdleTimeout = TimeSpan.FromMilliseconds(100) + } + }; + + var ignite = Ignition.Start(cfg); + Assert.AreEqual(100, ignite.GetConfiguration().ClientConnectorConfiguration.IdleTimeout.TotalMilliseconds); + + using (var client = StartClient()) + { + var cache = client.GetOrCreateCache<int, int>("foo"); + cache[1] = 1; + Assert.AreEqual(1, cache[1]); + + Thread.Sleep(90); + Assert.AreEqual(1, cache[1]); + + // Idle check frequency is 2 seconds. + Thread.Sleep(4000); + var ex = Assert.Throws<SocketException>(() => cache.Get(1)); + Assert.AreEqual(SocketError.ConnectionAborted, ex.SocketErrorCode); + } + } + + /// <summary> /// Starts the client. /// </summary> private static IIgniteClient StartClient() http://git-wip-us.apache.org/repos/asf/ignite/blob/1a939b0a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml index 1fc42ad..aff48f5 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml @@ -112,7 +112,7 @@ </memoryPolicies> </memoryConfiguration> <sqlConnectorConfiguration host='bar' port='10' portRange='11' socketSendBufferSize='12' socketReceiveBufferSize='13' tcpNoDelay='true' maxOpenCursorsPerConnection='14' threadPoolSize='15' /> - <clientConnectorConfiguration host='bar' port='10' portRange='11' socketSendBufferSize='12' socketReceiveBufferSize='13' tcpNoDelay='true' maxOpenCursorsPerConnection='14' threadPoolSize='15' /> + <clientConnectorConfiguration host='bar' port='10' portRange='11' socketSendBufferSize='12' socketReceiveBufferSize='13' tcpNoDelay='true' maxOpenCursorsPerConnection='14' threadPoolSize='15' idleTimeout = "00:00:19" /> <persistentStoreConfiguration alwaysWriteFullPages='true' checkpointingFrequency='00:00:1' checkpointingPageBufferSize='2' checkpointingThreads='3' lockWaitTime='00:00:04' persistentStorePath='foo' tlbSize='5' walArchivePath='bar' walFlushFrequency='00:00:06' walFsyncDelayNanos='7' walHistorySize='8' http://git-wip-us.apache.org/repos/asf/ignite/blob/1a939b0a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs index 167854d..5512975 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs @@ -250,6 +250,7 @@ namespace Apache.Ignite.Core.Tests Assert.IsTrue(client.TcpNoDelay); Assert.AreEqual(14, client.MaxOpenCursorsPerConnection); Assert.AreEqual(15, client.ThreadPoolSize); + Assert.AreEqual(19, client.IdleTimeout.TotalSeconds); var pers = cfg.PersistentStoreConfiguration; @@ -895,7 +896,8 @@ namespace Apache.Ignite.Core.Tests SocketReceiveBufferSize = 5, SocketSendBufferSize = 6, TcpNoDelay = false, - ThreadPoolSize = 7 + ThreadPoolSize = 7, + IdleTimeout = TimeSpan.FromMinutes(5) }, PersistentStoreConfiguration = new PersistentStoreConfiguration { http://git-wip-us.apache.org/repos/asf/ignite/blob/1a939b0a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs index 4d71929..0b1b499 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs @@ -594,6 +594,7 @@ namespace Apache.Ignite.Core.Tests Assert.AreEqual(ClientConnectorConfiguration.DefaultSocketBufferSize, cfg.SocketSendBufferSize); Assert.AreEqual(ClientConnectorConfiguration.DefaultTcpNoDelay, cfg.TcpNoDelay); Assert.AreEqual(ClientConnectorConfiguration.DefaultThreadPoolSize, cfg.ThreadPoolSize); + Assert.AreEqual(ClientConnectorConfiguration.DefaultIdleTimeout, cfg.IdleTimeout); } /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/1a939b0a/modules/platforms/dotnet/Apache.Ignite.Core/Configuration/ClientConnectorConfiguration.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Configuration/ClientConnectorConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Configuration/ClientConnectorConfiguration.cs index 8c23d99..a5b2403 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Configuration/ClientConnectorConfiguration.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Configuration/ClientConnectorConfiguration.cs @@ -17,9 +17,11 @@ namespace Apache.Ignite.Core.Configuration { + using System; using System.ComponentModel; using System.Diagnostics; using Apache.Ignite.Core.Binary; + using Apache.Ignite.Core.Impl.Binary; /// <summary> /// Client connector configuration (ODBC, JDBC, Thin Client). @@ -55,6 +57,11 @@ namespace Apache.Ignite.Core.Configuration /// Default SQL connector thread pool size. /// </summary> public static readonly int DefaultThreadPoolSize = IgniteConfiguration.DefaultThreadPoolSize; + + /// <summary> + /// Default idle timeout. + /// </summary> + public static TimeSpan DefaultIdleTimeout = TimeSpan.Zero; /// <summary> /// Initializes a new instance of the <see cref="ClientConnectorConfiguration"/> class. @@ -68,6 +75,7 @@ namespace Apache.Ignite.Core.Configuration TcpNoDelay = DefaultTcpNoDelay; MaxOpenCursorsPerConnection = DefaultMaxOpenCursorsPerConnection; ThreadPoolSize = DefaultThreadPoolSize; + IdleTimeout = DefaultIdleTimeout; } /// <summary> @@ -85,6 +93,7 @@ namespace Apache.Ignite.Core.Configuration TcpNoDelay = reader.ReadBoolean(); MaxOpenCursorsPerConnection = reader.ReadInt(); ThreadPoolSize = reader.ReadInt(); + IdleTimeout = reader.ReadLongAsTimespan(); } /// <summary> @@ -102,6 +111,7 @@ namespace Apache.Ignite.Core.Configuration writer.WriteBoolean(TcpNoDelay); writer.WriteInt(MaxOpenCursorsPerConnection); writer.WriteInt(ThreadPoolSize); + writer.WriteTimeSpanAsLong(IdleTimeout); } /// <summary> @@ -155,5 +165,12 @@ namespace Apache.Ignite.Core.Configuration /// Gets or sets the size of the thread pool. /// </summary> public int ThreadPoolSize { get; set; } + + /// <summary> + /// Gets or sets idle timeout for client connections on the server side. + /// If no packets come within idle timeout, the connection is closed by the server. + /// Zero or negative means no timeout. + /// </summary> + public TimeSpan IdleTimeout { get; set; } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/1a939b0a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd index 5d76cde..190b3ad 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd @@ -1442,6 +1442,11 @@ <xs:documentation>SQL connector thread pool size.</xs:documentation> </xs:annotation> </xs:attribute> + <xs:attribute name="idleTimeout" type="xs:string"> + <xs:annotation> + <xs:documentation>Idle timeout for client connections on the server side. If no packets come within idle timeout, the connection is closed by the server. Zero or negative for no timeout.</xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> <xs:element name="persistentStoreConfiguration" minOccurs="0">
