You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by al...@apache.org on 2020/07/15 14:57:52 UTC

[ignite] branch master updated: IGNITE-9379 Thin client: Fix critical errors handling - Fixes #8011.

This is an automated email from the ASF dual-hosted git repository.

alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 02586be  IGNITE-9379 Thin client: Fix critical errors handling - Fixes #8011.
02586be is described below

commit 02586bee3aa655c17a12cc4f96ae927711a3b108
Author: Aleksey Plekhanov <pl...@gmail.com>
AuthorDate: Wed Jul 15 19:54:37 2020 +0500

    IGNITE-9379 Thin client: Fix critical errors handling - Fixes #8011.
    
    Signed-off-by: Aleksey Plekhanov <pl...@gmail.com>
---
 .../processors/odbc/ClientListenerNioListener.java | 13 ++++++-
 .../processors/odbc/ClientListenerProcessor.java   |  6 ++-
 .../odbc/ClientListenerRequestHandler.java         |  2 +-
 .../processors/odbc/jdbc/JdbcRequestHandler.java   |  4 +-
 .../processors/odbc/odbc/OdbcRequestHandler.java   |  4 +-
 .../platform/client/ClientRequestHandler.java      |  2 +-
 .../org/apache/ignite/client/ReliabilityTest.java  | 43 +++++++++++++++++++++-
 7 files changed, 64 insertions(+), 10 deletions(-)

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 5052728..369eb2d 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
@@ -24,6 +24,8 @@ import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.configuration.ClientConnectorConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.ThinClientConfiguration;
+import org.apache.ignite.failure.FailureContext;
+import org.apache.ignite.failure.FailureType;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.MarshallerContextImpl;
 import org.apache.ignite.internal.binary.BinaryCachingMetadataHandler;
@@ -222,12 +224,15 @@ public class ClientListenerNioListener extends GridNioServerListenerAdapter<byte
                 });
             }
         }
-        catch (Exception e) {
+        catch (Throwable e) {
             handler.unregisterRequest(req.requestId());
 
             U.error(log, "Failed to process client request [req=" + req + ']', e);
 
             ses.send(parser.encode(handler.handleException(e, req)));
+
+            if (e instanceof Error)
+                throw (Error)e;
         }
     }
 
@@ -236,6 +241,12 @@ public class ClientListenerNioListener extends GridNioServerListenerAdapter<byte
         ses.close();
     }
 
+    /** {@inheritDoc} */
+    @Override public void onFailure(FailureType failureType, Throwable failure) {
+        if (failure instanceof OutOfMemoryError)
+            ctx.failure().process(new FailureContext(failureType, failure));
+    }
+
     /**
      * Schedule handshake timeout.
      * @param ses Connection session.
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 d467878..ecebc4a 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
@@ -36,6 +36,7 @@ import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.OdbcConfiguration;
 import org.apache.ignite.configuration.SqlConnectorConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.managers.communication.GridIoPolicy;
 import org.apache.ignite.internal.managers.systemview.walker.ClientConnectionViewWalker;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import org.apache.ignite.internal.processors.authentication.AuthorizationContext;
@@ -55,6 +56,7 @@ import org.apache.ignite.mxbean.ClientProcessorMXBean;
 import org.apache.ignite.spi.IgnitePortProtocol;
 import org.apache.ignite.spi.systemview.view.ClientConnectionView;
 import org.apache.ignite.thread.IgniteThreadPoolExecutor;
+import org.apache.ignite.thread.OomExceptionHandler;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -141,7 +143,9 @@ public class ClientListenerProcessor extends GridProcessorAdapter {
                     cliConnCfg.getThreadPoolSize(),
                     cliConnCfg.getThreadPoolSize(),
                     0,
-                    new LinkedBlockingQueue<Runnable>());
+                    new LinkedBlockingQueue<Runnable>(),
+                    GridIoPolicy.UNDEFINED,
+                    new OomExceptionHandler(ctx));
 
                 Exception lastErr = null;
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerRequestHandler.java
index e6a1b8b..e9f0e13 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/ClientListenerRequestHandler.java
@@ -38,7 +38,7 @@ public interface ClientListenerRequestHandler {
      * @param req Request.
      * @return Error response.
      */
-    ClientListenerResponse handleException(Exception e, ClientListenerRequest req);
+    ClientListenerResponse handleException(Throwable e, ClientListenerRequest req);
 
     /**
      * Write successful handshake response.
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
index a2270c8..aeedfcf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
@@ -512,7 +512,7 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
     }
 
     /** {@inheritDoc} */
-    @Override public ClientListenerResponse handleException(Exception e, ClientListenerRequest req) {
+    @Override public ClientListenerResponse handleException(Throwable e, ClientListenerRequest req) {
         return exceptionToResult(e);
     }
 
@@ -1327,7 +1327,7 @@ public class JdbcRequestHandler implements ClientListenerRequestHandler {
      * @param e Exception to convert.
      * @return resulting {@link JdbcResponse}.
      */
-    private JdbcResponse exceptionToResult(Exception e) {
+    private JdbcResponse exceptionToResult(Throwable e) {
         if (e instanceof QueryCancelledException)
             return new JdbcResponse(IgniteQueryErrorCode.QUERY_CANCELED, e.getMessage());
         if (e instanceof TransactionSerializationException)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
index 181f671..d0a2766 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
@@ -267,7 +267,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
     }
 
     /** {@inheritDoc} */
-    @Override public ClientListenerResponse handleException(Exception e, ClientListenerRequest req) {
+    @Override public ClientListenerResponse handleException(Throwable e, ClientListenerRequest req) {
         return exceptionToResult(e);
     }
 
@@ -989,7 +989,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
      * @param e Exception to convert.
      * @return resulting {@link OdbcResponse}.
      */
-    private static OdbcResponse exceptionToResult(Exception e) {
+    private static OdbcResponse exceptionToResult(Throwable e) {
         String msg = OdbcUtils.tryRetrieveH2ErrorMessage(e);
 
         if (e instanceof TransactionSerializationException)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java
index 98d2ac1..1c820a7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequestHandler.java
@@ -108,7 +108,7 @@ public class ClientRequestHandler implements ClientListenerRequestHandler {
     }
 
     /** {@inheritDoc} */
-    @Override public ClientListenerResponse handleException(Exception e, ClientListenerRequest req) {
+    @Override public ClientListenerResponse handleException(Throwable e, ClientListenerRequest req) {
         assert req != null;
         assert e != null;
 
diff --git a/modules/core/src/test/java/org/apache/ignite/client/ReliabilityTest.java b/modules/core/src/test/java/org/apache/ignite/client/ReliabilityTest.java
index 8e0a74c..a9f54e3 100644
--- a/modules/core/src/test/java/org/apache/ignite/client/ReliabilityTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/client/ReliabilityTest.java
@@ -38,16 +38,22 @@ import org.apache.ignite.cache.query.Query;
 import org.apache.ignite.cache.query.QueryCursor;
 import org.apache.ignite.cache.query.ScanQuery;
 import org.apache.ignite.configuration.ClientConfiguration;
+import org.apache.ignite.failure.FailureHandler;
+import org.apache.ignite.internal.client.thin.AbstractThinClientTest;
+import org.apache.ignite.internal.client.thin.ClientServerError;
 import org.apache.ignite.internal.processors.odbc.ClientListenerProcessor;
 import org.apache.ignite.mxbean.ClientProcessorMXBean;
 import org.apache.ignite.testframework.GridTestUtils;
-import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.junit.Test;
 
+import static org.apache.ignite.events.EventType.EVTS_CACHE;
+import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ;
+import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED;
+
 /**
  * High Availability tests.
  */
-public class ReliabilityTest extends GridCommonAbstractTest {
+public class ReliabilityTest extends AbstractThinClientTest {
     /**
      * Thin clint failover.
      */
@@ -304,6 +310,39 @@ public class ReliabilityTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Test server-side critical error.
+     */
+    @Test
+    public void testServerCriticalError() throws Exception {
+        AtomicBoolean failure = new AtomicBoolean();
+
+        FailureHandler hnd = (ignite, ctx) -> failure.compareAndSet(false, true);
+
+        try (Ignite ignite = startGrid(getConfiguration().setFailureHandler(hnd)
+            .setIncludeEventTypes(EVTS_CACHE)); IgniteClient client = startClient(ignite)
+        ) {
+            ClientCache<Object, Object> cache = client.getOrCreateCache(DEFAULT_CACHE_NAME);
+
+            cache.put(0, 0);
+
+            String msg = "critical error message";
+
+            ignite.events().localListen(e -> { throw new Error(msg); }, EVT_CACHE_OBJECT_READ);
+
+            GridTestUtils.assertThrowsAnyCause(log, () -> cache.get(0), ClientServerError.class, msg);
+
+            assertFalse(failure.get());
+
+            // OutOfMemoryError should also invoke failure handler.
+            ignite.events().localListen(e -> { throw new OutOfMemoryError(msg); }, EVT_CACHE_OBJECT_REMOVED);
+
+            GridTestUtils.assertThrowsAnyCause(log, () -> cache.remove(0), ClientServerError.class, msg);
+
+            assertTrue(GridTestUtils.waitForCondition(failure::get, 1_000L));
+        }
+    }
+
+    /**
      * Drop all thin client connections on given Ignite instance.
      *
      * @param ignite Ignite.