From 422d23c7329163c8f7578d5af8b1334e57bae647 Mon Sep 17 00:00:00 2001 From: Fadhil Kurnia Date: Fri, 22 Mar 2024 12:11:36 -0400 Subject: [PATCH 1/3] add config to enable/disable leader election during startup --- src/edu/umass/cs/gigapaxos/PaxosConfig.java | 18 ++++++++++++++++++ .../gigapaxos/PaxosInstanceStateMachine.java | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/src/edu/umass/cs/gigapaxos/PaxosConfig.java b/src/edu/umass/cs/gigapaxos/PaxosConfig.java index ba0f4556..393ddc00 100644 --- a/src/edu/umass/cs/gigapaxos/PaxosConfig.java +++ b/src/edu/umass/cs/gigapaxos/PaxosConfig.java @@ -919,6 +919,24 @@ public static enum PC implements Config.ConfigurableEnum, FORWARD_PREEMPTED_REQUESTS(true), + /** + * If true, an active replica will start leader election process (i.e., + * Phase 1 of Paxos) during startup, when it has not yet run for coordinator. + * Checkout {@link PaxosInstanceStateMachine#notRunYet()}. Note that this + * option ensures better liveness since replica groups will have an + * elected coordinator faster. However, the options can cause flaky + * leadership during replica group startup: rapid leader changes before + * a long-running coordinator is elected. + * + * If false, there will be a coordinator chosen deterministically during + * startup, even when all the Nodes do not start with Phase 1 of Paxos. + * This option is more stable but can cause liveness issue when the + * deterministically chosen coordinator during startup suddenly crashed, + * making all the Nodes need to wait until coordinator timeout. + * + */ + ENABLE_STARTUP_LEADER_ELECTION(true), + /** * FIXME: The options below only exist for testing stringification diff --git a/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java b/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java index 956a7d82..592dd9cd 100644 --- a/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java +++ b/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java @@ -135,6 +135,9 @@ public class PaxosInstanceStateMachine implements Keyable, Pausable { private static final boolean ENABLE_INSTRUMENTATION = Config .getGlobalBoolean(PC.ENABLE_INSTRUMENTATION); + private static final boolean ENABLE_STARTUP_LEADER_ELECTION = Config. + getGlobalBoolean(PC.ENABLE_STARTUP_LEADER_ELECTION); + private static final boolean instrument() { return ENABLE_INSTRUMENTATION; } @@ -2153,6 +2156,9 @@ private synchronized PaxosCoordinator tryMakeCoordinator(Ballot newBallot) { } private boolean notRunYet() { + if (!ENABLE_STARTUP_LEADER_ELECTION) { + return false; + } return this.paxosState.notRunYet(); } From 0157aca34b28dd471b4b8d0707b17c81ecfcb681 Mon Sep 17 00:00:00 2001 From: Fadhil Kurnia Date: Fri, 22 Mar 2024 12:15:41 -0400 Subject: [PATCH 2/3] for consistency, change the term LEADER to COORDINATOR --- src/edu/umass/cs/gigapaxos/PaxosConfig.java | 21 +++++++++---------- .../gigapaxos/PaxosInstanceStateMachine.java | 6 +++--- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/edu/umass/cs/gigapaxos/PaxosConfig.java b/src/edu/umass/cs/gigapaxos/PaxosConfig.java index 393ddc00..ac64aed2 100644 --- a/src/edu/umass/cs/gigapaxos/PaxosConfig.java +++ b/src/edu/umass/cs/gigapaxos/PaxosConfig.java @@ -40,7 +40,6 @@ import edu.umass.cs.nio.SSLDataProcessingWorker; import edu.umass.cs.nio.SSLDataProcessingWorker.SSL_MODES; import edu.umass.cs.nio.interfaces.NodeConfig; -import edu.umass.cs.reconfiguration.interfaces.ReconfigurableNodeConfig; import edu.umass.cs.reconfiguration.interfaces.ReplicableRequest; import edu.umass.cs.utils.Config; import edu.umass.cs.utils.DiskMap; @@ -920,22 +919,22 @@ public static enum PC implements Config.ConfigurableEnum, FORWARD_PREEMPTED_REQUESTS(true), /** - * If true, an active replica will start leader election process (i.e., - * Phase 1 of Paxos) during startup, when it has not yet run for coordinator. - * Checkout {@link PaxosInstanceStateMachine#notRunYet()}. Note that this - * option ensures better liveness since replica groups will have an - * elected coordinator faster. However, the options can cause flaky - * leadership during replica group startup: rapid leader changes before - * a long-running coordinator is elected. - * + * If true, an Active Replica will start coordinator election process + * (i.e., Phase 1 of Paxos or Leader Election) during startup, when an + * Active has not yet run for a Coordinator. + * Checkout {@link PaxosInstanceStateMachine#notRunYet()}. + * Note that this option ensures better liveness since replica groups + * will have an elected coordinator faster. However, the options can cause + * flaky leadership during replica group startup: rapid leader changes + * before a long-running coordinator is elected. + *

* If false, there will be a coordinator chosen deterministically during * startup, even when all the Nodes do not start with Phase 1 of Paxos. * This option is more stable but can cause liveness issue when the * deterministically chosen coordinator during startup suddenly crashed, * making all the Nodes need to wait until coordinator timeout. - * */ - ENABLE_STARTUP_LEADER_ELECTION(true), + ENABLE_STARTUP_COORDINATOR_ELECTION(true), /** diff --git a/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java b/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java index 592dd9cd..8564a06f 100644 --- a/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java +++ b/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java @@ -135,8 +135,8 @@ public class PaxosInstanceStateMachine implements Keyable, Pausable { private static final boolean ENABLE_INSTRUMENTATION = Config .getGlobalBoolean(PC.ENABLE_INSTRUMENTATION); - private static final boolean ENABLE_STARTUP_LEADER_ELECTION = Config. - getGlobalBoolean(PC.ENABLE_STARTUP_LEADER_ELECTION); + private static final boolean ENABLE_STARTUP_COORDINATOR_ELECTION = Config. + getGlobalBoolean(PC.ENABLE_STARTUP_COORDINATOR_ELECTION); private static final boolean instrument() { return ENABLE_INSTRUMENTATION; @@ -2156,7 +2156,7 @@ private synchronized PaxosCoordinator tryMakeCoordinator(Ballot newBallot) { } private boolean notRunYet() { - if (!ENABLE_STARTUP_LEADER_ELECTION) { + if (!ENABLE_STARTUP_COORDINATOR_ELECTION) { return false; } return this.paxosState.notRunYet(); From 6b037798aa6fa1353659c904a81b8638a358bd7a Mon Sep 17 00:00:00 2001 From: Fadhil Kurnia Date: Mon, 25 Mar 2024 14:04:33 -0400 Subject: [PATCH 3/3] fix indentation of notRunYet() and its surounding methods --- src/edu/umass/cs/gigapaxos/PaxosAcceptor.java | 14 +++++++------- .../cs/gigapaxos/PaxosInstanceStateMachine.java | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/edu/umass/cs/gigapaxos/PaxosAcceptor.java b/src/edu/umass/cs/gigapaxos/PaxosAcceptor.java index b274e10c..a847a908 100644 --- a/src/edu/umass/cs/gigapaxos/PaxosAcceptor.java +++ b/src/edu/umass/cs/gigapaxos/PaxosAcceptor.java @@ -76,15 +76,15 @@ public class PaxosAcceptor { .isLoggingEnabled() || SQLPaxosLogger.isJournalingEnabled(); // active but never run for coordinator yet -protected boolean notRunYet() { - return this.state == (byte)STATES.ACTIVE_1.ordinal(); -} + protected boolean notRunYet() { + return this.state == (byte)STATES.ACTIVE_1.ordinal(); + } -protected void setActive2() { - this.state = (byte)STATES.ACTIVE_2.ordinal(); -} + protected void setActive2() { + this.state = (byte)STATES.ACTIVE_2.ordinal(); + } -protected static enum STATES { + protected static enum STATES { RECOVERY, ACTIVE_1, // active, haven't yet run for coordinator ACTIVE_2, // active, have run for coordinator at least once diff --git a/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java b/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java index 8564a06f..5e5111b9 100644 --- a/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java +++ b/src/edu/umass/cs/gigapaxos/PaxosInstanceStateMachine.java @@ -2155,14 +2155,14 @@ private synchronized PaxosCoordinator tryMakeCoordinator(Ballot newBallot) { this.paxosState.getSlot(), false); } -private boolean notRunYet() { - if (!ENABLE_STARTUP_COORDINATOR_ELECTION) { - return false; - } + private boolean notRunYet() { + if (!ENABLE_STARTUP_COORDINATOR_ELECTION) { + return false; + } return this.paxosState.notRunYet(); -} + } -private String getBallots() { + private String getBallots() { return "[" + (this.coordinator != null ? "C:(" + (this.coordinator != null ? this.coordinator