petrov-mg commented on code in PR #11176:
URL: https://github.com/apache/ignite/pull/11176#discussion_r1485634448


##########
modules/core/src/test/java/org/apache/ignite/internal/client/thin/BlockingTxOpsTest.java:
##########
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client.thin;
+
+import java.util.TreeSet;
+import java.util.concurrent.ThreadLocalRandom;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.client.ClientCache;
+import org.apache.ignite.client.ClientCacheConfiguration;
+import org.apache.ignite.client.ClientTransaction;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.junit.Test;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static 
org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static 
org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
+
+/**
+ * Thin client blocking transactional operations tests.
+ */
+public class BlockingTxOpsTest extends AbstractThinClientTest {

Review Comment:
   I suggest to create a dedicated minimal test for the fixed case when 
asynchronous cache operations from different client transactions can be chained 
in one future, which in turn leads to transactions hanging.
   
   I assume that it can be reproduced with just one key and two threads.
   
   I also suggest to create a test for the case when a client transaction 
resuming results in a merge of an existing active asynchronous cache operation 
and a restored one.



##########
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java:
##########
@@ -3653,6 +3654,52 @@ public void awaitLastFut() {
         }
     }
 
+    /**
+     * Replaces previous async operation future on transaction suspend.
+     */
+    public @Nullable FutureHolder suspendLastFut() {
+        FutureHolder holder = lastFut.get();
+
+        IgniteInternalFuture fut = holder.future();
+
+        if (fut != null && !fut.isDone()) {
+            lastFut.set(new FutureHolder());
+
+            return holder;
+        }
+        else
+            return null;
+    }
+
+    /**
+     * Replaces previous async operation future on transaction resume.
+     */
+    public void resumeLastFut(FutureHolder holder) {
+        IgniteInternalFuture resumedFut = holder.future();
+
+        if (resumedFut == null || resumedFut.isDone())
+            return;
+
+        FutureHolder threadHolder = lastFut.get();
+
+        IgniteInternalFuture threadFut = threadHolder.future();
+
+        if (threadFut != null && !threadFut.isDone()) {
+            threadHolder.lock();

Review Comment:
   It seems that we should acquire lock before checking that `threadFut` is not 
null and is not completed, because `FutureHolder` can be cleared concurrently.



##########
modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientRequest.java:
##########
@@ -58,4 +59,21 @@ public ClientRequest(long reqId) {
     public ClientResponse process(ClientConnectionContext ctx) {
         return new ClientResponse(reqId);
     }
+
+    /**
+     * Processes the request asynchronously.
+     *
+     * @return Future for response.
+     */
+    public IgniteInternalFuture<ClientResponse> 
processAsync(ClientConnectionContext ctx) {

Review Comment:
   Have you considered just replacing the "process" method with "processAsync"?
   
   For the first glance it might help avoid creating `isAsync` method and 
ClientListenerAsyncResponse. It looks a bit confusing that it's up to a outer 
code to decide whether to run `sync` or `async` method to process 
`ClientRequest` while `ClientRequest` itself knows how it should be processed.
   
   On the other hand it will lead to creating CompletedFuture wrappers and a 
bit of refactoring.



##########
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java:
##########
@@ -3653,6 +3654,52 @@ public void awaitLastFut() {
         }
     }
 
+    /**
+     * Replaces previous async operation future on transaction suspend.
+     */
+    public @Nullable FutureHolder suspendLastFut() {
+        FutureHolder holder = lastFut.get();
+
+        IgniteInternalFuture fut = holder.future();
+
+        if (fut != null && !fut.isDone()) {
+            lastFut.set(new FutureHolder());
+
+            return holder;
+        }
+        else
+            return null;
+    }
+
+    /**
+     * Replaces previous async operation future on transaction resume.
+     */
+    public void resumeLastFut(FutureHolder holder) {
+        IgniteInternalFuture resumedFut = holder.future();
+
+        if (resumedFut == null || resumedFut.isDone())
+            return;
+
+        FutureHolder threadHolder = lastFut.get();
+
+        IgniteInternalFuture threadFut = threadHolder.future();
+
+        if (threadFut != null && !threadFut.isDone()) {
+            threadHolder.lock();
+
+            try {
+                GridCompoundFuture f = new 
GridCompoundFuture<>().add(threadFut).add(resumedFut).markInitialized();

Review Comment:
   I'm not sure, but shouldn't we use here `EmbeddedFuture` instead of 
`CompoundFuture`? Like it is done in 
`GridCacheAdapter#asyncOp(GridNearTxLocal,GridCacheAdapter.AsyncOp<T>, 
CacheOperationContext, boolean)`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to