Pavel Pereslegin created IGNITE-26927:
-----------------------------------------

             Summary: Java thin. Sql. A race between close() and 
fetchNextPage() in ResultSet may result in an error
                 Key: IGNITE-26927
                 URL: https://issues.apache.org/jira/browse/IGNITE-26927
             Project: Ignite
          Issue Type: Bug
          Components: sql ai3, thin clients ai3
            Reporter: Pavel Pereslegin


Consider the following example:
{code:java}
  var rs = sql.executeAsync(null, "SELECT...").join();

  rs.fetchNextPage(); // SQL_CURSOR_NEXT_PAGE
  rs.close(); // SQL_CURSOR_CLOSE
{code}

In the above case, the SQL_CURSOR_CLOSE request is sent to the server before 
the result of the SQL_CURSOR_NEXT_PAGE request is received.

The SQL_CURSOR_NEXT_PAGE request handler, if the last requested page removes 
the client resource (see ClientSqlCursorNextPageRequest.process())
The SQL_CURSOR_CLOSE request handler may fail with the error "Failed to find 
resource with id" if SQL_CURSOR_NEXT_PAGE has already removed this resource.

The problem is even more important for the synchronous API due to optimization, 
which always requests the next data page in the background.

Reproducer:
{code:java}
  @Test
  void resourceNotFoundOnClose() {
      IgniteSql sql = client().sql();

      Statement stmt = sql.statementBuilder()
              .query("SELECT * FROM TABLE(SYSTEM_RANGE(0, 1))") // 2 rows
              .pageSize(1) // 1 row
              .build();

      for (int attempt = 0; attempt < 1000; attempt++) {
          var rs = sql.execute(null, stmt); // preloads 2-nd page in the 
background (see SyncResultSetAdapter.IteratorImpl constructor)
          rs.close(); // Fails with "Failed to find resource"
      }
  }
{code}

Stacktrace:
{noformat}
Caused by: org.apache.ignite.internal.lang.IgniteInternalException: 
IGN-CMN-65535 Failed to find resource with id: 23 TraceId:e40ee6a7
  at 
org.apache.ignite.client.handler.ClientResourceRegistry.remove(ClientResourceRegistry.java:95)
  at 
org.apache.ignite.client.handler.requests.sql.ClientSqlCursorCloseRequest.process(ClientSqlCursorCloseRequest.java:35)
  at 
org.apache.ignite.client.handler.ClientInboundMessageHandler.processOperation(ClientInboundMessageHandler.java:994)
  at 
org.apache.ignite.client.handler.ClientInboundMessageHandler.processOperationInternal(ClientInboundMessageHandler.java:1103)
{noformat}

We need to fix this issue properly.

Some thoughts worth considering:
* Completely ignoring the exception is bad, because we might miss another 
resource leak problem.
* Removing background preloading in SyncResultSetAdapter is bad because it 
negatively affects performance.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to