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

av 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 0c5cb48  IGNITE-15702 Control.sh consistency check command should 
support status option (#9529)
0c5cb48 is described below

commit 0c5cb48b4eac1c056caca93f85c85eeeb6ce2281
Author: Anton Vinogradov <a...@apache.org>
AuthorDate: Tue Nov 9 17:06:59 2021 +0300

    IGNITE-15702 Control.sh consistency check command should support status 
option (#9529)
---
 docs/_docs/tools/control-script.adoc               | 22 ++++-
 .../consistency/ConsistencyCommand.java            | 17 +++-
 .../consistency/ConsistencySubCommand.java         |  6 +-
 .../ignite/util/KillCommandsCommandShTest.java     | 40 ++++++++-
 .../cache/IgniteCacheOffheapManagerImpl.java       | 14 ++--
 .../visor/consistency/AbstractConsistencyTask.java | 64 +++++++++++++++
 .../consistency/VisorConsistencyRepairTask.java    | 48 ++---------
 .../consistency/VisorConsistencyRepairTaskArg.java | 19 +++++
 .../consistency/VisorConsistencyStatusTask.java    | 95 ++++++++++++++++++++++
 ...Result.java => VisorConsistencyTaskResult.java} |  2 +-
 .../main/resources/META-INF/classnames.properties  |  2 +-
 ...ridCommandHandlerClusterByClassTest_help.output |  4 +
 ...andHandlerClusterByClassWithSSLTest_help.output |  4 +
 13 files changed, 281 insertions(+), 56 deletions(-)

diff --git a/docs/_docs/tools/control-script.adoc 
b/docs/_docs/tools/control-script.adoc
index 24b9972..527ef0c 100644
--- a/docs/_docs/tools/control-script.adoc
+++ b/docs/_docs/tools/control-script.adoc
@@ -977,6 +977,8 @@ Parameters:
 
 == Cache Consistency
 
+=== Repair
+
 The command allows to perform cache consistency check and repair (when 
possible) using Read Repair approach.
 
 [tabs]
@@ -999,4 +1001,22 @@ Parameters:
 | Parameter | Description
 | `cache-name`| Cache to be checked/repaired..
 | `partition`| Cache's partition to be checked/repaired.
-|===
\ No newline at end of file
+|===
+
+=== Status
+
+The command allows performing cache consistency check/repair operations status 
check.
+
+[tabs]
+--
+tab:Unix[]
+[source,shell]
+----
+control.sh --enable-experimental --consistency status
+----
+tab:Window[]
+[source,shell]
+----
+control.bat --enable-experimental --consistency status
+----
+--
diff --git 
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/consistency/ConsistencyCommand.java
 
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/consistency/ConsistencyCommand.java
index 10ef23a..46e2760 100644
--- 
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/consistency/ConsistencyCommand.java
+++ 
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/consistency/ConsistencyCommand.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.commandline.consistency;
 
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.logging.Logger;
@@ -28,18 +29,19 @@ import org.apache.ignite.internal.commandline.Command;
 import org.apache.ignite.internal.commandline.CommandArgIterator;
 import org.apache.ignite.internal.commandline.CommandLogger;
 import 
org.apache.ignite.internal.visor.consistency.VisorConsistencyRepairTaskArg;
-import 
org.apache.ignite.internal.visor.consistency.VisorConsistencyRepairTaskResult;
+import org.apache.ignite.internal.visor.consistency.VisorConsistencyTaskResult;
 
 import static org.apache.ignite.internal.commandline.CommandList.CONSISTENCY;
 import static 
org.apache.ignite.internal.commandline.TaskExecutor.BROADCAST_UUID;
 import static 
org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
 import static 
org.apache.ignite.internal.commandline.consistency.ConsistencySubCommand.REPAIR;
+import static 
org.apache.ignite.internal.commandline.consistency.ConsistencySubCommand.STATUS;
 import static 
org.apache.ignite.internal.commandline.consistency.ConsistencySubCommand.of;
 
 /**
  *
  */
-public class ConsistencyCommand extends 
AbstractCommand<VisorConsistencyRepairTaskArg> {
+public class ConsistencyCommand extends AbstractCommand<Object> {
     /** Command argument. */
     private VisorConsistencyRepairTaskArg cmdArg;
 
@@ -53,7 +55,7 @@ public class ConsistencyCommand extends 
AbstractCommand<VisorConsistencyRepairTa
         StringBuilder sb = new StringBuilder();
 
         try (GridClient client = Command.startClient(clientCfg)) {
-            VisorConsistencyRepairTaskResult res = executeTaskByNameOnNode(
+            VisorConsistencyTaskResult res = executeTaskByNameOnNode(
                 client,
                 cmd.taskName(),
                 arg(),
@@ -115,6 +117,13 @@ public class ConsistencyCommand extends 
AbstractCommand<VisorConsistencyRepairTa
             REPAIR.toString(),
             "cache-name",
             "partition");
+
+        usage(
+            log,
+            "Cache consistency check/repair operations status:",
+            CONSISTENCY,
+            Collections.emptyMap(),
+            STATUS.toString());
     }
 
     /** {@inheritDoc} */
@@ -127,6 +136,8 @@ public class ConsistencyCommand extends 
AbstractCommand<VisorConsistencyRepairTa
 
             cmdArg = new VisorConsistencyRepairTaskArg(cacheName, part);
         }
+        else if (cmd == STATUS)
+            cmdArg = null;
         else
             throw new IllegalArgumentException("Unsupported operation.");
     }
diff --git 
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/consistency/ConsistencySubCommand.java
 
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/consistency/ConsistencySubCommand.java
index a8b5fee..046ab7f 100644
--- 
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/consistency/ConsistencySubCommand.java
+++ 
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/consistency/ConsistencySubCommand.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.commandline.consistency;
 
 import org.apache.ignite.internal.visor.consistency.VisorConsistencyRepairTask;
+import org.apache.ignite.internal.visor.consistency.VisorConsistencyStatusTask;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -25,7 +26,10 @@ import org.jetbrains.annotations.Nullable;
  */
 public enum ConsistencySubCommand {
     /** Repair. */
-    REPAIR("repair", VisorConsistencyRepairTask.class.getName());
+    REPAIR("repair", VisorConsistencyRepairTask.class.getName()),
+
+    /** Status. */
+    STATUS("status", VisorConsistencyStatusTask.class.getName());
 
     /** Sub-command name. */
     private final String name;
diff --git 
a/modules/control-utility/src/test/java/org/apache/ignite/util/KillCommandsCommandShTest.java
 
b/modules/control-utility/src/test/java/org/apache/ignite/util/KillCommandsCommandShTest.java
index 8334084..ed19f72 100644
--- 
a/modules/control-utility/src/test/java/org/apache/ignite/util/KillCommandsCommandShTest.java
+++ 
b/modules/control-utility/src/test/java/org/apache/ignite/util/KillCommandsCommandShTest.java
@@ -24,6 +24,7 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
@@ -31,6 +32,7 @@ import 
org.apache.ignite.internal.TestRecordingCommunicationSpi;
 import 
org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.visor.consistency.VisorConsistencyRepairTask;
+import org.apache.ignite.internal.visor.consistency.VisorConsistencyStatusTask;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.spi.systemview.view.ComputeJobView;
@@ -228,10 +230,13 @@ public class KillCommandsCommandShTest extends 
GridCommandHandlerClusterByClassA
 
         cfg.setName(consistencyCancheName);
         cfg.setBackups(SERVER_NODE_CNT - 1);
+        cfg.setAffinity(new RendezvousAffinityFunction().setPartitions(1));
 
         IgniteCache<Integer, Integer> cache = client.getOrCreateCache(cfg);
 
-        for (int i = 0; i < 10_000; i++)
+        int entries = 10_000;
+
+        for (int i = 0; i < entries; i++)
             cache.put(i, i);
 
         AtomicInteger getCnt = new AtomicInteger();
@@ -248,7 +253,16 @@ public class KillCommandsCommandShTest extends 
GridCommandHandlerClusterByClassA
                 assertTrue(F.iterator0(jobs, true, 
repairJobFilter).hasNext()); // Found.
             }
 
-            int res = execute("--kill", "consistency");
+            int res = execute("--consistency", "status");
+
+            assertEquals(EXIT_CODE_OK, res);
+
+            assertContains(log, testOut.toString(), "Status: 1024/" + entries);
+            assertNotContains(log, testOut.toString(), 
VisorConsistencyStatusTask.NOTHING_FOUND);
+
+            testOut.reset();
+
+            res = execute("--kill", "consistency");
 
             assertEquals(EXIT_CODE_OK, res);
 
@@ -271,16 +285,25 @@ public class KillCommandsCommandShTest extends 
GridCommandHandlerClusterByClassA
             thLatch.countDown();
         });
 
+        // GridNearGetRequest messages count required to pefrom getAll() with 
readRepair from all nodes twice.
+        // First will be finished (which generates status), second will be 
frozen.
+        int twiceGetMsgCnt = SERVER_NODE_CNT * (SERVER_NODE_CNT - 1) * 2;
+
         for (IgniteEx server : srvs) {
             TestRecordingCommunicationSpi spi =
                 
((TestRecordingCommunicationSpi)server.configuration().getCommunicationSpi());
 
+            AtomicInteger locLimit = new AtomicInteger(SERVER_NODE_CNT - 1);
+
             spi.blockMessages((node, message) -> {
                 if (message instanceof GridNearGetRequest) { // Get request 
caused by read repair operation.
-                    if (getCnt.incrementAndGet() == SERVER_NODE_CNT) // Each 
node should send a get request.
+                    // Each node should perform get twice.
+                    if (getCnt.incrementAndGet() == twiceGetMsgCnt)
                         th.start();
 
-                    return true; // Blocking to freeze '--consistency repair' 
operation.
+                    assertTrue(getCnt.get() <= twiceGetMsgCnt); // 
Cancellation should stop the process.
+
+                    return locLimit.decrementAndGet() < 0; // Blocking to 
freeze '--consistency repair' operation (except first get).
                 }
 
                 return false;
@@ -303,5 +326,14 @@ public class KillCommandsCommandShTest extends 
GridCommandHandlerClusterByClassA
 
             spi.stopBlock();
         }
+
+        testOut.reset();
+
+        int res = execute("--consistency", "status");
+
+        assertEquals(EXIT_CODE_OK, res);
+
+        assertContains(log, testOut.toString(), 
VisorConsistencyStatusTask.NOTHING_FOUND);
+        assertNotContains(log, testOut.toString(), "Status");
     }
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
index ed32121..8507b57 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
@@ -30,6 +30,7 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.LongAdder;
 import java.util.function.Supplier;
 import javax.cache.Cache;
 import javax.cache.processor.EntryProcessor;
@@ -1444,7 +1445,7 @@ public class IgniteCacheOffheapManagerImpl implements 
IgniteCacheOffheapManager
         protected final PartitionUpdateCounter pCntr;
 
         /** Partition size. */
-        private final AtomicLong storageSize = new AtomicLong();
+        private final LongAdder storageSize = new LongAdder();
 
         /** */
         private final IntMap<AtomicLong> cacheSizes = new IntRWHashMap<>();
@@ -1551,7 +1552,7 @@ public class IgniteCacheOffheapManagerImpl implements 
IgniteCacheOffheapManager
                 return size != null ? (int)size.get() : 0;
             }
 
-            return storageSize.get();
+            return storageSize.sum();
         }
 
         /** {@inheritDoc} */
@@ -1568,7 +1569,7 @@ public class IgniteCacheOffheapManagerImpl implements 
IgniteCacheOffheapManager
 
         /** {@inheritDoc} */
         @Override public long fullSize() {
-            return storageSize.get();
+            return storageSize.sum();
         }
 
         /**
@@ -1580,7 +1581,7 @@ public class IgniteCacheOffheapManagerImpl implements 
IgniteCacheOffheapManager
                  * TODO https://issues.apache.org/jira/browse/IGNITE-10082
                  * Using of counters is cheaper than tree operations. Return 
size checking after the ticked is resolved.
                  */
-                return grp.mvccEnabled() ? dataTree.isEmpty() : 
storageSize.get() == 0;
+                return grp.mvccEnabled() ? dataTree.isEmpty() : 
storageSize.sum() == 0;
             }
             catch (IgniteCheckedException e) {
                 
U.error(grp.shared().logger(IgniteCacheOffheapManagerImpl.class), "Failed to 
perform operation.", e);
@@ -1591,7 +1592,7 @@ public class IgniteCacheOffheapManagerImpl implements 
IgniteCacheOffheapManager
 
         /** {@inheritDoc} */
         @Override public void updateSize(int cacheId, long delta) {
-            storageSize.addAndGet(delta);
+            storageSize.add(delta);
 
             if (grp.sharedGroup()) {
                 AtomicLong size = cacheSizes.get(cacheId);
@@ -3069,7 +3070,8 @@ public class IgniteCacheOffheapManagerImpl implements 
IgniteCacheOffheapManager
         public void restoreState(long size, long updCntr, @Nullable 
Map<Integer, Long> cacheSizes, byte[] cntrUpdData) {
             pCntr.init(updCntr, cntrUpdData);
 
-            storageSize.set(size);
+            storageSize.reset();
+            storageSize.add(size);
 
             if (cacheSizes != null) {
                 for (Map.Entry<Integer, Long> e : cacheSizes.entrySet())
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/AbstractConsistencyTask.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/AbstractConsistencyTask.java
new file mode 100644
index 0000000..20dc406
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/AbstractConsistencyTask.java
@@ -0,0 +1,64 @@
+/*
+ * 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.visor.consistency;
+
+import java.util.List;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.compute.ComputeJobResult;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.visor.VisorMultiNodeTask;
+
+/**
+ * Base class for Consistency tasks.
+ *
+ * @param <A> Task argument type.
+ * @param <J> Job result type
+ */
+public abstract class AbstractConsistencyTask<A, J> extends 
VisorMultiNodeTask<A, VisorConsistencyTaskResult, J> {
+    /** {@inheritDoc} */
+    @Override protected VisorConsistencyTaskResult 
reduce0(List<ComputeJobResult> results) throws IgniteException {
+        VisorConsistencyTaskResult taskRes = new VisorConsistencyTaskResult();
+        StringBuilder sb = new StringBuilder();
+
+        for (ComputeJobResult res : results) {
+            if (res.isCancelled())
+                taskRes.cancelled(true);
+
+            Exception e = res.getException();
+
+            if (e != null) {
+                taskRes.failed(true);
+
+                sb.append("Node: ").append(res.getNode()).append("\n")
+                    .append("  Exception: ").append(e).append("\n")
+                    .append(X.getFullStackTrace(e)).append("\n");
+            }
+
+            String data = res.getData();
+
+            if (data != null)
+                sb.append("Node: ").append(res.getNode()).append("\n")
+                    .append("  Result: ").append(data).append("\n");
+        }
+
+        if (sb.length() != 0)
+            taskRes.message(sb.toString());
+
+        return taskRes;
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTask.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTask.java
index 47f6eae..1380bee 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTask.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTask.java
@@ -18,7 +18,6 @@
 package org.apache.ignite.internal.visor.consistency;
 
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import javax.cache.CacheException;
@@ -27,7 +26,6 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.compute.ComputeJobResult;
 import org.apache.ignite.events.CacheConsistencyViolationEvent;
 import org.apache.ignite.internal.processors.cache.CacheGroupContext;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
@@ -37,9 +35,7 @@ import 
org.apache.ignite.internal.processors.cache.distributed.near.consistency.
 import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
 import org.apache.ignite.internal.util.GridConcurrentHashSet;
 import org.apache.ignite.internal.util.lang.GridCursor;
-import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.visor.VisorJob;
-import org.apache.ignite.internal.visor.VisorMultiNodeTask;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.apache.ignite.resources.LoggerResource;
 
@@ -48,8 +44,7 @@ import static 
org.apache.ignite.events.EventType.EVT_CONSISTENCY_VIOLATION;
 /**
  *
  */
-public class VisorConsistencyRepairTask extends
-    VisorMultiNodeTask<VisorConsistencyRepairTaskArg, 
VisorConsistencyRepairTaskResult, String> {
+public class VisorConsistencyRepairTask extends 
AbstractConsistencyTask<VisorConsistencyRepairTaskArg, String> {
     /** Serial version uid. */
     private static final long serialVersionUID = 0L;
 
@@ -67,37 +62,6 @@ public class VisorConsistencyRepairTask extends
         return new VisorConsistencyRepairJob(arg, debug);
     }
 
-    /** {@inheritDoc} */
-    @Override protected VisorConsistencyRepairTaskResult 
reduce0(List<ComputeJobResult> results) throws IgniteException {
-        VisorConsistencyRepairTaskResult taskRes = new 
VisorConsistencyRepairTaskResult();
-        StringBuilder sb = new StringBuilder();
-
-        for (ComputeJobResult res : results) {
-            if (res.isCancelled())
-                taskRes.cancelled(true);
-
-            Exception e = res.getException();
-
-            if (e != null) {
-                taskRes.failed(true);
-
-                sb.append("Node: ").append(res.getNode()).append("\n")
-                    .append("  Exception: ").append(e).append("\n")
-                    .append(X.getFullStackTrace(e)).append("\n");
-            }
-
-            String data = res.getData();
-
-            if (data != null)
-                sb.append("Node: ").append(res.getNode()).append("\n")
-                    .append("  Result: ").append(data).append("\n\n");
-        }
-
-        taskRes.message(sb.toString());
-
-        return taskRes;
-    }
-
     /**
      *
      */
@@ -149,6 +113,8 @@ public class VisorConsistencyRepairTask extends
 
             log.info("Consistency check started [grp=" + 
grpCtx.cacheOrGroupName() + ", part=" + p + "]");
 
+            VisorConsistencyStatusTask.MAP.put(arg, "0/" + part.fullSize());
+
             long cnt = 0;
             long statusTs = 0;
 
@@ -198,6 +164,8 @@ public class VisorConsistencyRepairTask extends
 
                             log.info("Consistency check progress [grp=" + 
grpCtx.cacheOrGroupName() +
                                 ", part=" + p + ", checked=" + cnt + "/" + 
part.fullSize() + "]");
+
+                            VisorConsistencyStatusTask.MAP.put(arg, cnt + "/" 
+ part.fullSize());
                         }
 
                     }
@@ -212,12 +180,14 @@ public class VisorConsistencyRepairTask extends
             }
             finally {
                 part.release();
+
+                VisorConsistencyStatusTask.MAP.remove(arg);
             }
 
             if (!evts.isEmpty())
                 return processEvents(cctx, p, cnt);
             else
-                return NOTHING_FOUND + " [processed=" + cnt + "]";
+                return NOTHING_FOUND + " [processed=" + cnt + "]\n";
         }
 
         /**
@@ -266,7 +236,7 @@ public class VisorConsistencyRepairTask extends
                 return CONSISTENCY_VIOLATIONS_FOUND + " [found=" + found + ", 
fixed=" + fixed + ", processed=" + cnt + "]";
             }
             else
-                return NOTHING_FOUND + " [processed=" + cnt + "]";
+                return NOTHING_FOUND + " [processed=" + cnt + "]\n";
         }
 
         /**
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTaskArg.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTaskArg.java
index ffcbf4e..134cda2 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTaskArg.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTaskArg.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.visor.consistency;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.util.Objects;
 import org.apache.ignite.internal.dto.IgniteDataTransferObject;
 import org.apache.ignite.internal.util.typedef.internal.U;
 
@@ -77,4 +78,22 @@ public class VisorConsistencyRepairTaskArg extends 
IgniteDataTransferObject {
     public int part() {
         return part;
     }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        VisorConsistencyRepairTaskArg arg = (VisorConsistencyRepairTaskArg)o;
+
+        return part == arg.part && Objects.equals(cacheName, arg.cacheName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        return Objects.hash(cacheName, part);
+    }
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyStatusTask.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyStatusTask.java
new file mode 100644
index 0000000..af001e6
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyStatusTask.java
@@ -0,0 +1,95 @@
+/*
+ * 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.visor.consistency;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.compute.ComputeJobResult;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.resources.LoggerResource;
+
+/**
+ *
+ */
+public class VisorConsistencyStatusTask extends AbstractConsistencyTask<Void, 
String> {
+    /** Serial version uid. */
+    private static final long serialVersionUID = 0L;
+
+    /** Nothing found. */
+    public static final String NOTHING_FOUND = "Consistency check/repair 
operations were NOT found.";
+
+    /** Status map. */
+    public static final ConcurrentHashMap<VisorConsistencyRepairTaskArg, 
String> MAP = new ConcurrentHashMap<>();
+
+    /** {@inheritDoc} */
+    @Override protected VisorJob<Void, String> job(Void arg) {
+        return new VisorConsistencyStatusJob(arg, debug);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected VisorConsistencyTaskResult 
reduce0(List<ComputeJobResult> results) throws IgniteException {
+        VisorConsistencyTaskResult taskRes = super.reduce0(results);
+
+        if (taskRes.message() == null)
+            taskRes.message(NOTHING_FOUND);
+
+        return taskRes;
+    }
+
+    /**
+     *
+     */
+    private static class VisorConsistencyStatusJob extends VisorJob<Void, 
String> {
+        /** Serial version uid. */
+        private static final long serialVersionUID = 0L;
+
+        /** Injected logger. */
+        @LoggerResource
+        protected IgniteLogger log;
+
+        /**
+         * @param arg Arguments.
+         * @param debug Debug.
+         */
+        protected VisorConsistencyStatusJob(Void arg, boolean debug) {
+            super(arg, debug);
+        }
+
+        /** {@inheritDoc} */
+        @Override protected String run(Void arg) throws IgniteException {
+            if (MAP.isEmpty())
+                return null;
+
+            StringBuilder sb = new StringBuilder();
+
+            for (Map.Entry<VisorConsistencyRepairTaskArg, String> entry : 
MAP.entrySet()) {
+                VisorConsistencyRepairTaskArg args = entry.getKey();
+                String status = entry.getValue();
+
+                sb.append("\n    Cache: 
").append(args.cacheName()).append("\n")
+                    .append("    Partition: ").append(args.part()).append("\n")
+                    .append("    Status: ").append(status).append("\n");
+            }
+
+            return sb.toString();
+        }
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTaskResult.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyTaskResult.java
similarity index 96%
rename from 
modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTaskResult.java
rename to 
modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyTaskResult.java
index 51e6d64..6c0eb21 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyRepairTaskResult.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/consistency/VisorConsistencyTaskResult.java
@@ -26,7 +26,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 /**
  *
  */
-public class VisorConsistencyRepairTaskResult extends IgniteDataTransferObject 
{
+public class VisorConsistencyTaskResult extends IgniteDataTransferObject {
     /** */
     private static final long serialVersionUID = 0L;
 
diff --git a/modules/core/src/main/resources/META-INF/classnames.properties 
b/modules/core/src/main/resources/META-INF/classnames.properties
index 1bb7a46..8ed15fc 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -2010,7 +2010,7 @@ 
org.apache.ignite.internal.visor.baseline.VisorBaselineTaskResult
 org.apache.ignite.internal.visor.baseline.VisorBaselineViewTask
 
org.apache.ignite.internal.visor.baseline.VisorBaselineViewTask$VisorBaselineViewJob
 org.apache.ignite.internal.visor.consistency.VisorConsistencyRepairTaskArg
-org.apache.ignite.internal.visor.consistency.VisorConsistencyRepairTaskResult
+org.apache.ignite.internal.visor.consistency.VisorConsistencyTaskResult
 org.apache.ignite.internal.visor.misc.VisorIdAndTagViewTaskResult
 org.apache.ignite.internal.visor.misc.VisorClusterChangeTagTaskResult
 org.apache.ignite.internal.visor.shutdown.VisorShutdownPolicyTask
diff --git 
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
 
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
index e7ad1e6..6a0ca41 100644
--- 
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
+++ 
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
@@ -309,6 +309,10 @@ If the file name isn't specified the output file name is: 
'<typeId>.bin'
       cache-name  - Cache to be checked/repaired.
       partition   - Cache's partition to be checked/repaired.
 
+  [EXPERIMENTAL]
+  Cache consistency check/repair operations status:
+    control.(sh|bat) --consistency status
+
 By default commands affecting the cluster require interactive confirmation.
 Use --yes option to disable it.
 
diff --git 
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
 
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
index e7ad1e6..6a0ca41 100644
--- 
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
+++ 
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
@@ -309,6 +309,10 @@ If the file name isn't specified the output file name is: 
'<typeId>.bin'
       cache-name  - Cache to be checked/repaired.
       partition   - Cache's partition to be checked/repaired.
 
+  [EXPERIMENTAL]
+  Cache consistency check/repair operations status:
+    control.(sh|bat) --consistency status
+
 By default commands affecting the cluster require interactive confirmation.
 Use --yes option to disable it.
 

Reply via email to