bdeggleston commented on code in PR #4708:
URL: https://github.com/apache/cassandra/pull/4708#discussion_r3444054967


##########
src/java/org/apache/cassandra/locator/SatelliteFailoverState.java:
##########
@@ -0,0 +1,272 @@
+/*
+ * 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.cassandra.locator;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.common.base.Preconditions;
+
+import org.apache.cassandra.dht.Range;
+import org.apache.cassandra.dht.Token;
+
+/**
+ * Failover state management for satellite datacenter replication
+ *
+ * Tracks per-range failover state to support different replica layouts / 
consistency requirements
+ * during different failover states to maintain correctness
+ *
+ * NOTE: Initial implementation stores state in memory. Future work will 
integrate
+ * with TCM for cluster-wide coordination and persistence.
+ */
+public class SatelliteFailoverState
+{
+    /**
+     * Failover state for a range or keyspace.
+     *
+     * Each state corresponds to a specific phase in the failover process as 
defined
+     * in CEP-58, with different consistency level requirements.
+     */
+    public enum State
+    {
+        /**
+         * Normal operation: Primary DC + satellite active.
+         * Read/Write CL: QUORUM_OF_QUORUMS (primary + satellite OR secondary)
+         */
+        NORMAL,
+
+        /**
+         * First stage of failover. Waits for a QoQ to acknowledge new state 
before moving to
+         * TRANSITION state. During TRANSITION_ACK, coordinators will not 
start paxos operations, and the
+         * primary transition state machine will not transition to the 
transition state until it confirms
+         * that a QoQ nodes for a range are also on TRANSITION_ACK. This 
temporary gap in paxos availability
+         * prevents the different full dcs from performing conflicting paxos 
operations concurrently.
+         */
+        TRANSITION_ACK,
+
+        /**
+         *
+         * Currently syncing to new primary, once sync is complete, failover 
state will transition to NORMAL
+         * for this range
+         */
+        TRANSITION,
+    }
+
+    /**
+     * Failover state with DC context.
+     *
+     * Tracks which DC we're failing over from. The target DC is always the 
current
+     * primary DC configured in the replication strategy, enabling failover 
between
+     * any configured DCs via schema change (ALTER KEYSPACE ... WITH 
replication = {'primary': 'DC2'}).
+     */
+    public static class FailoverInfo
+    {
+        private final State state;
+        private final String fromDC;  // DC we're failing over from (old 
primary), null for NORMAL
+
+        /**
+         * Create failover info.
+         *
+         * @param state The failover state
+         * @param fromDC The old primary DC we're failing from (null for 
NORMAL state)
+         */
+        public FailoverInfo(State state, String fromDC)
+        {
+            this.state = state;
+            this.fromDC = fromDC;
+
+            switch (state)
+            {
+                case NORMAL:
+                    Preconditions.checkArgument(fromDC == null);
+                    break;
+                case TRANSITION_ACK:
+                case TRANSITION:
+                    Preconditions.checkArgument(fromDC != null);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown state: " + 
state);
+            }
+
+        }
+
+        /**
+         * Get the failover state.
+         */
+        public State getState()
+        {
+            return state;
+        }
+
+        /**
+         * Get the DC we're failing over FROM (old primary).
+         * Returns null for NORMAL state.
+         */
+        public String getFromDC()
+        {
+            return fromDC;
+        }
+
+        /**
+         * Create NORMAL state (no failover in progress).
+         */
+        public static FailoverInfo normal()
+        {
+            return new FailoverInfo(State.NORMAL, null);
+        }
+
+        /**
+         * Create TRANSITION_ACK state.
+         *
+         * @param fromDC The old primary DC we're failing over from
+         */
+        public static FailoverInfo transitionAck(String fromDC)
+        {
+            return new FailoverInfo(State.TRANSITION_ACK, fromDC);
+        }
+
+        /**
+         * Create TRANSITION state
+         *
+         * @param fromDC The old primary DC we're transferring from
+         */
+        public static FailoverInfo transition(String fromDC)
+        {
+            return new FailoverInfo(State.TRANSITION, fromDC);
+        }
+
+        @Override
+        public String toString()
+        {
+            if (fromDC == null)
+                return state.toString();
+            return String.format("%s(from=%s)", state, fromDC);
+        }
+
+        public boolean isTransitioning()
+        {
+            switch (state)
+            {
+                case TRANSITION:
+                case TRANSITION_ACK:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    }
+
+    /**
+     * Container for per-range failover state.
+     *
+     * Stores failover state indexed by token range, enabling different ranges
+     * to be in different failover states (though initial implementation uses
+     * uniform state across all ranges).
+     *
+     * NOTE: This is in-memory for initial implementation. Future work will
+     * store this in TCM for persistence and cluster-wide coordination.
+     */
+    public static class FailoverStateMap

Review Comment:
   Failover is advanced on a per-range basis, we don't failover the entire ring 
at once. The failover process is the next ticket, this is just a mock failover 
state for testing and we do test range reads across failover boundaries



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