belliottsmith commented on code in PR #3877:
URL: https://github.com/apache/cassandra/pull/3877#discussion_r1950569836


##########
src/java/org/apache/cassandra/db/virtual/AccordVirtualTables.java:
##########
@@ -17,32 +17,204 @@
  */
 package org.apache.cassandra.db.virtual;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import javax.annotation.Nullable;
+
+import com.google.common.collect.Sets;
+
+import accord.api.ConfigurationService;
+import accord.primitives.Range;
+import accord.primitives.Ranges;
+import accord.topology.TopologyManager;
+import accord.utils.async.AsyncResult;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.cql3.statements.schema.CreateTableStatement;
+import org.apache.cassandra.db.marshal.LongType;
+import org.apache.cassandra.dht.LocalPartitioner;
+import org.apache.cassandra.schema.Schema;
+import org.apache.cassandra.schema.TableId;
 import org.apache.cassandra.schema.TableMetadata;
+import org.apache.cassandra.service.accord.AccordService;
+import org.apache.cassandra.service.accord.TokenRange;
 
 public class AccordVirtualTables
 {
-    private AccordVirtualTables() {}
+    private static final String SUCCESS = "success";
+
+    private AccordVirtualTables()
+    {
+    }
 
     public static Collection<VirtualTable> getAll(String keyspace)
     {
         if (!DatabaseDescriptor.getAccordTransactionsEnabled())
             return Collections.emptyList();
 
-        return List.of(
+        return List.of(new EpochReadyTable(keyspace),
+                       new EpochSyncRanges(keyspace)
         );
     }
 
-    private static TableMetadata parse(String keyspace, String comment, String 
query)
+    private static TableMetadata.Builder parse(String keyspace, String query)
     {
         return CreateTableStatement.parse(query, keyspace)
-                                   .comment(comment)
-                                   .kind(TableMetadata.Kind.VIRTUAL)
-                                   .build();
+                                   .kind(TableMetadata.Kind.VIRTUAL);
+    }
+
+    public static class EpochReadyTable extends AbstractVirtualTable
+    {
+        public EpochReadyTable(String keyspace)
+        {
+            super(parse(keyspace, "CREATE TABLE accord_epoch_ready (\n" +
+                                      "  epoch bigint PRIMARY KEY,\n" +
+                                      "  ready_metadata text,\n" +
+                                      "  ready_coordinate text,\n" +
+                                      "  ready_data text,\n" +
+                                      "  ready_reads text,\n" +
+                                      "  ready boolean,\n" +
+                                      ")")
+                  .partitioner(new LocalPartitioner(LongType.instance))
+                  .comment("Exposes the epoch ready state for recieved epochs 
in Accord")
+                  .build());
+        }
+
+        @Override
+        public DataSet data()
+        {
+            AccordService service = accordService();
+            SimpleDataSet ds = new SimpleDataSet(metadata());
+            TopologyManager tm = service.node().topology();
+            long minEpoch = tm.minEpoch();
+            long maxEpoch = tm.epoch();
+            for (long epoch = minEpoch; epoch <= maxEpoch; epoch++)
+            {
+                TopologyManager.EpochState state = 
tm.getEpochStateUnsafe(epoch);
+                if (state == null)
+                    continue;
+                // When state is null there are 2 possible things going on
+                // 1) race condition with epoch evicition; this should impact 
the starting epochs such as min.  If this happens there isn't a reason to 
display the epochs as they were evicited.
+                // 2) gap!  A gap should not be possible and would be a bug (N 
exists, N + 2 exists, N + 1 does not exist).  This table exposes such a gap by 
having a missing row.
+                ds.row(epoch);
+                ConfigurationService.EpochReady ready = state.ready();
+                if (ready != null)
+                {
+                    ds.column("ready_metadata", 
resultToString(ready.metadata));
+                    ds.column("ready_coordinate", 
resultToString(ready.coordinate));
+                    ds.column("ready_data", resultToString(ready.data));
+                    ds.column("ready_reads", resultToString(ready.reads));
+                    boolean success = ready.reads.isSuccess();
+                    ds.column("ready", success);
+                    // There is a race condition given these fields are 
AsyncResults; checking it twice could get different results!
+                    // If ready_reads was set to "pending", then the next 
check its "success", make sure to update the field
+                    // to avoid any confussion.
+                    if (success)
+                        ds.column("ready_reads", SUCCESS);
+                }
+                else
+                {
+                    ds.column("ready", false);
+                }
+            }
+            return ds;
+        }
+    }
+
+    public static class EpochSyncRanges extends AbstractVirtualTable
+    {
+        protected EpochSyncRanges(String keyspace)
+        {
+            super(parse(keyspace, "CREATE TABLE accord_epoch_ranges (\n" +

Review Comment:
   maybe `accord_epochs` and `accord_table_epochs`?
   
   Not sure that's better, just an idea, since one is node level data and the 
other is table level data.



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to