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

tledkov 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 b7682cc  IGNITE-13119 fix data race when getting index rebuild status 
(#7901)
b7682cc is described below

commit b7682cc9d49fbaa8a7392f4e41ce2916a23481b3
Author: ktkalenko <ktkale...@gridgain.com>
AuthorDate: Mon Jun 8 12:15:48 2020 +0300

    IGNITE-13119 fix data race when getting index rebuild status (#7901)
---
 .../processors/query/h2/IgniteH2Indexing.java      |  9 ++-
 .../query/h2/GridIndexRebuildSelfTest.java         | 66 +++++++++++++++++++++-
 2 files changed, 69 insertions(+), 6 deletions(-)

diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index 48990fd..df6089c 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -1996,6 +1996,9 @@ public class IgniteH2Indexing implements 
GridQueryIndexing {
 
         GridFutureAdapter<Void> rebuildCacheIdxFut = new GridFutureAdapter<>();
 
+        //to avoid possible data race
+        GridFutureAdapter<Void> outRebuildCacheIdxFut = new 
GridFutureAdapter<>();
+
         rebuildCacheIdxFut.listen(fut -> {
             Throwable err = fut.error();
 
@@ -2005,18 +2008,18 @@ public class IgniteH2Indexing implements 
GridQueryIndexing {
                 }
                 catch (Throwable t) {
                     err = t;
-
-                    rebuildCacheIdxFut.onDone(t);
                 }
             }
 
             if (nonNull(err))
                 U.error(log, "Failed to rebuild indexes for cache: " + 
cacheName, err);
+
+            outRebuildCacheIdxFut.onDone(err);
         });
 
         rebuildIndexesFromHash0(cctx, clo, rebuildCacheIdxFut);
 
-        return rebuildCacheIdxFut;
+        return outRebuildCacheIdxFut;
     }
 
     /**
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexRebuildSelfTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexRebuildSelfTest.java
index 3a6301b..8aa902b 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexRebuildSelfTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexRebuildSelfTest.java
@@ -37,6 +37,7 @@ import 
org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
 import 
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager;
 import org.apache.ignite.internal.processors.query.GridQueryIndexing;
 import org.apache.ignite.internal.processors.query.GridQueryProcessor;
+import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
 import 
org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitorClosure;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.lang.GridCursor;
@@ -45,6 +46,9 @@ import org.junit.Test;
 
 import static java.util.Objects.nonNull;
 import static java.util.Objects.requireNonNull;
+import static 
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.INDEX_FILE_NAME;
+import static 
org.apache.ignite.internal.processors.query.QueryUtils.DFLT_SCHEMA;
+import static org.apache.ignite.internal.util.IgniteUtils.delete;
 
 /**
  * Index rebuild after node restart test.
@@ -100,6 +104,8 @@ public class GridIndexRebuildSelfTest extends 
DynamicIndexAbstractSelfTest {
         cleanPersistenceDir();
 
         INSTANCE = this;
+
+        BlockingIndexing.slowRebuildIdxFut = false;
     }
 
     /** {@inheritDoc} */
@@ -154,7 +160,7 @@ public class GridIndexRebuildSelfTest extends 
DynamicIndexAbstractSelfTest {
 
         stopAllGrids();
 
-        assertTrue(U.delete(idxPath));
+        assertTrue(delete(idxPath));
 
         srv = startServer();
 
@@ -185,6 +191,46 @@ public class GridIndexRebuildSelfTest extends 
DynamicIndexAbstractSelfTest {
     }
 
     /**
+     * Test checks that there will be no data race between notifications about 
index rebuilding
+     * and an indication that index has been rebuilt.
+     *
+     * Steps:
+     * 1)Create a node with data filling;
+     * 2)Stopping a node with deletion index.bin;
+     * 3)Set a delay between notification and a note about index rebuilding;
+     * 4)Restarting node with waiting index rebuild;
+     * 5)Checking that index is not being rebuilt.
+     *
+     * @throws Exception if failed.
+     */
+    @Test
+    public void testDataRaceWhenMarkIdxRebuild() throws Exception {
+        IgniteEx srv = startServer();
+
+        IgniteInternalCache internalCache = createAndFillTableWithIndex(srv);
+
+        File idxFile = indexFile(internalCache);
+
+        stopAllGrids();
+
+        assertTrue(delete(idxFile));
+
+        BlockingIndexing.slowRebuildIdxFut = true;
+
+        srv = startServer();
+
+        srv.cache(CACHE_NAME).indexReadyFuture().get();
+
+        IgniteH2Indexing idx = 
(IgniteH2Indexing)srv.context().query().getIndexing();
+
+        GridH2Table tbl = idx.schemaManager().dataTable(DFLT_SCHEMA, 
CACHE_NAME);
+
+        assertNotNull(tbl);
+
+        assertFalse(tbl.rebuildFromHashInProgress());
+    }
+
+    /**
      * Check that index rebuild uses the number of threads
      * that specified in configuration.
      *
@@ -207,7 +253,7 @@ public class GridIndexRebuildSelfTest extends 
DynamicIndexAbstractSelfTest {
 
         stopAllGrids();
 
-        assertTrue(U.delete(idxPath));
+        assertTrue(delete(idxPath));
 
         buildIdxThreadPoolSize = buildIdxThreadCnt;
 
@@ -260,7 +306,7 @@ public class GridIndexRebuildSelfTest extends 
DynamicIndexAbstractSelfTest {
         File cacheWorkDir = 
((FilePageStoreManager)internalCache.context().shared().pageStore())
             .cacheWorkDir(internalCache.configuration());
 
-        return cacheWorkDir.toPath().resolve("index.bin").toFile();
+        return cacheWorkDir.toPath().resolve(INDEX_FILE_NAME).toFile();
     }
 
     /**
@@ -342,6 +388,9 @@ public class GridIndexRebuildSelfTest extends 
DynamicIndexAbstractSelfTest {
         /** Flag to ignore first rebuild performed on initial node start. */
         private boolean firstRbld = true;
 
+        /** Flag for slowing down {@code rebuildIdxFut} to reproduce data 
race. */
+        static boolean slowRebuildIdxFut;
+
         /** {@inheritDoc} */
         @Override protected void rebuildIndexesFromHash0(
             GridCacheContext cctx,
@@ -359,6 +408,17 @@ public class GridIndexRebuildSelfTest extends 
DynamicIndexAbstractSelfTest {
             else
                 firstRbld = false;
 
+            if (slowRebuildIdxFut) {
+                rebuildIdxFut.listen(fut -> {
+                    try {
+                        U.sleep(1_000);
+                    }
+                    catch (IgniteInterruptedCheckedException e) {
+                        log.error("Error while slow down " + fut, e);
+                    }
+                });
+            }
+
             super.rebuildIndexesFromHash0(cctx, clo, rebuildIdxFut);
         }
     }

Reply via email to