-
Notifications
You must be signed in to change notification settings - Fork 1.9k
IGNITE-20973 Unusable thin client timeout #12569
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
a051e32
e4cd7a0
12dfe5d
5ce6f48
87e229e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,7 @@ | |
| import org.apache.ignite.client.SslProtocol; | ||
| import org.apache.ignite.internal.client.thin.TcpIgniteClient; | ||
| import org.apache.ignite.internal.util.typedef.internal.S; | ||
| import org.apache.ignite.internal.util.typedef.internal.U; | ||
|
|
||
| /** | ||
| * {@link TcpIgniteClient} configuration. | ||
|
|
@@ -57,8 +58,11 @@ public final class ClientConfiguration implements Serializable { | |
| /** @serial Tcp no delay. */ | ||
| private boolean tcpNoDelay = true; | ||
|
|
||
| /** @serial Timeout. 0 means infinite. */ | ||
| private int timeout; | ||
| /** @serial Connection timeout in milliseconds. 0 means infinite. */ | ||
| private int connTimeout; | ||
|
|
||
| /** @serial Request timeout in milliseconds. 0 means infinite. */ | ||
| private int reqTimeout; | ||
timoninmaxim marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /** @serial Send buffer size. 0 means system default. */ | ||
| private int sndBufSize = 32 * 1024; | ||
|
|
@@ -227,19 +231,62 @@ public ClientConfiguration setTcpNoDelay(boolean tcpNoDelay) { | |
| } | ||
|
|
||
| /** | ||
| * @return Send/receive timeout in milliseconds. | ||
| * @deprecated Use {@link #getConnectionTimeout()} and {@link #getRequestTimeout()} instead. | ||
| * @return Request timeout in milliseconds. | ||
| */ | ||
| @Deprecated | ||
| public int getTimeout() { | ||
timoninmaxim marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return timeout; | ||
| if (reqTimeout != connTimeout ) | ||
| U.warn(logger, String.format( | ||
| "Deprecated getTimeout() API is used while request timeout (%d) differs from connection timeout (%d). " + | ||
| "Returning request timeout. Please use getRequestTimeout() and getConnectionTimeout() instead.", | ||
| reqTimeout, connTimeout | ||
| )); | ||
|
|
||
| return reqTimeout; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add WARN log if |
||
| } | ||
|
|
||
| /** | ||
| * @deprecated Use {@link #setConnectionTimeout(int)} and {@link #setRequestTimeout(int)} instead. | ||
| * @param timeout Send/receive timeout in milliseconds. | ||
| * @return {@code this} for chaining. | ||
| */ | ||
| @Deprecated | ||
| public ClientConfiguration setTimeout(int timeout) { | ||
| this.timeout = timeout; | ||
| this.connTimeout = timeout; | ||
| this.reqTimeout = timeout; | ||
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * @return Connection timeout in milliseconds. 0 means infinite. | ||
| */ | ||
| public int getConnectionTimeout() { | ||
| return connTimeout; | ||
| } | ||
|
|
||
| /** | ||
| * @param connTimeout Connection timeout in milliseconds. 0 means infinite. | ||
| * @return {@code this} for chaining. | ||
| */ | ||
| public ClientConfiguration setConnectionTimeout(int connTimeout) { | ||
| this.connTimeout = connTimeout; | ||
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * @return Request timeout in milliseconds. 0 means infinite. | ||
| */ | ||
| public int getRequestTimeout() { | ||
| return reqTimeout; | ||
| } | ||
|
|
||
| /** | ||
| * @param reqTimeout Request timeout in milliseconds. 0 means infinite. | ||
| * @return {@code this} for chaining. | ||
| */ | ||
| public ClientConfiguration setRequestTimeout(int reqTimeout) { | ||
| this.reqTimeout = reqTimeout; | ||
| return this; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,7 @@ | |
| import org.apache.ignite.configuration.ClientConfiguration; | ||
| import org.apache.ignite.configuration.ClientConnectorConfiguration; | ||
| import org.apache.ignite.configuration.IgniteConfiguration; | ||
| import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException; | ||
| import org.apache.ignite.internal.IgniteInternalFuture; | ||
| import org.apache.ignite.internal.binary.streams.BinaryOutputStream; | ||
| import org.apache.ignite.internal.binary.streams.BinaryStreams; | ||
|
|
@@ -67,7 +68,7 @@ public class TimeoutTest extends AbstractThinClientTest { | |
|
|
||
| /** {@inheritDoc} */ | ||
| @Override protected ClientConfiguration getClientConfiguration() { | ||
| return super.getClientConfiguration().setTimeout(TIMEOUT); | ||
| return super.getClientConfiguration().setConnectionTimeout(TIMEOUT).setRequestTimeout(TIMEOUT); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -217,4 +218,107 @@ public void testClientTimeoutOnOperation() throws Exception { | |
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Test that connection timeout is independent of request timeout during connection establishment. | ||
| */ | ||
| @Test | ||
| @SuppressWarnings("ThrowableNotThrown") | ||
| public void testConnectionTimeoutIndependentOfRequest() throws Exception { | ||
| ServerSocket sock = new ServerSocket(); | ||
| sock.bind(new InetSocketAddress("127.0.0.1", DFLT_PORT)); | ||
|
|
||
| CountDownLatch connectionAccepted = new CountDownLatch(1); | ||
|
|
||
| IgniteInternalFuture<?> fut = GridTestUtils.runAsync(() -> { | ||
| try { | ||
| Socket accepted = sock.accept(); | ||
| connectionAccepted.countDown(); | ||
|
|
||
| Thread.sleep(2000); | ||
|
|
||
| U.closeQuiet(accepted); | ||
| } | ||
| catch (Exception e) { | ||
| throw new IgniteException("Accept thread failed: " + e.getMessage(), e); | ||
| } | ||
| }); | ||
|
|
||
| try { | ||
| ClientConfiguration cfg = new ClientConfiguration() | ||
| .setAddresses("127.0.0.1:" + DFLT_PORT) | ||
| .setConnectionTimeout(500) | ||
| .setRequestTimeout(Integer.MAX_VALUE); | ||
|
|
||
| GridTestUtils.assertThrowsWithCause( | ||
timoninmaxim marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| () -> Ignition.startClient(cfg), | ||
| IgniteFutureTimeoutCheckedException.class | ||
| ); | ||
| } | ||
| finally { | ||
| U.closeQuiet(sock); | ||
| } | ||
|
|
||
| assertTrue("Connection should have been accepted", connectionAccepted.await(1, TimeUnit.SECONDS)); | ||
|
|
||
| fut.get(); | ||
| } | ||
|
|
||
| /** | ||
| * Test that request timeout is independent of connection timeout during operations. | ||
| */ | ||
| @Test | ||
| @SuppressWarnings("ThrowableNotThrown") | ||
| public void testRequestTimeoutIndependentOfConnection() throws Exception { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar for this test:
|
||
| IgniteConfiguration igniteCfg = getConfiguration(getTestIgniteInstanceName()); | ||
| igniteCfg.setClientConnectorConfiguration(new ClientConnectorConfiguration().setHandshakeTimeout(Integer.MAX_VALUE)); | ||
|
|
||
| try (Ignite ignite = startGrid(igniteCfg)) { | ||
| ClientConfiguration cfg = getClientConfiguration(ignite) | ||
| .setConnectionTimeout(Integer.MAX_VALUE) | ||
| .setRequestTimeout(500); | ||
|
|
||
| try (IgniteClient client = Ignition.startClient(cfg)) { | ||
| ClientCache<Object, Object> cache = client.getOrCreateCache("testTimeoutCache"); | ||
|
|
||
| ClientCacheConfiguration txCacheCfg = new ClientCacheConfiguration() | ||
| .setName("txCache") | ||
| .setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); | ||
|
|
||
| ClientCache<Object, Object> txCache = client.getOrCreateCache(txCacheCfg); | ||
|
|
||
| CyclicBarrier barrier = new CyclicBarrier(2); | ||
|
|
||
| IgniteInternalFuture<?> blockingThread = GridTestUtils.runAsync(() -> { | ||
| try (ClientTransaction ignored1 = client.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { | ||
| txCache.put(1, "blocked"); | ||
|
|
||
| barrier.await(2, TimeUnit.SECONDS); | ||
|
|
||
| // Wait for main thread to time out | ||
| barrier.await(2, TimeUnit.SECONDS); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For which reason you awaits main thread after sleeping? |
||
| } | ||
| catch (Exception e) { | ||
| throw new IgniteException(e); | ||
| } | ||
| }); | ||
|
|
||
| barrier.await(2, TimeUnit.SECONDS); | ||
|
|
||
| try (ClientTransaction ignored1 = client.transactions().txStart(PESSIMISTIC, REPEATABLE_READ)) { | ||
| GridTestUtils.assertThrowsWithCause( | ||
| () -> txCache.put(1, "should timeout"), | ||
| IgniteFutureTimeoutCheckedException.class | ||
| ); | ||
| } | ||
|
|
||
| barrier.await(2, TimeUnit.SECONDS); | ||
|
|
||
| cache.put(2, "still works"); | ||
| assertEquals("still works", cache.get(2)); | ||
|
|
||
| blockingThread.get(); | ||
| } | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check that actual javadocs contains lines started with 'serial'. For which purpose this tag is used?