From 33cc83fb9f5120019cb07d1bfae84b04c971d601 Mon Sep 17 00:00:00 2001 From: Hellblazer Date: Mon, 10 Jun 2024 21:06:56 -0700 Subject: [PATCH] limit bootstrapping to min of 4. fix RingIterator logic. --- .../apollo/ethereal/memberships/ChRbcGossip.java | 13 ++++--------- .../java/com/salesforce/apollo/fireflies/View.java | 6 +++--- .../salesforce/apollo/fireflies/ViewManagement.java | 6 ++++++ .../com/salesforce/apollo/ring/RingIterator.java | 7 ++++--- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/ethereal/src/main/java/com/salesforce/apollo/ethereal/memberships/ChRbcGossip.java b/ethereal/src/main/java/com/salesforce/apollo/ethereal/memberships/ChRbcGossip.java index 829b7e2de..225fcee21 100644 --- a/ethereal/src/main/java/com/salesforce/apollo/ethereal/memberships/ChRbcGossip.java +++ b/ethereal/src/main/java/com/salesforce/apollo/ethereal/memberships/ChRbcGossip.java @@ -28,9 +28,7 @@ import org.slf4j.LoggerFactory; import java.time.Duration; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.Optional; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -42,8 +40,8 @@ import static com.salesforce.apollo.ethereal.memberships.comm.GossiperClient.getCreate; /** - * Handles the gossip propigation of proposals, commits and preVotes from this node, as well as the notification of the - * adder of such from other nodes. + * Handles the gossip propagation of proposals, the commits and preVotes from this node, and the notification of the + * Adder of such events from other nodes. * * @author hal.hildebrand */ @@ -59,7 +57,6 @@ public class ChRbcGossip { private final SliceIterator ring; private final AtomicBoolean started = new AtomicBoolean(); private final Terminal terminal = new Terminal(); - private final List membership; private volatile ScheduledFuture scheduled; public ChRbcGossip(Digest id, SigningMember member, Collection membership, Processor processor, @@ -68,12 +65,10 @@ public ChRbcGossip(Digest id, SigningMember member, Collection membershi this.member = member; this.metrics = m; this.id = id; - this.membership = new ArrayList<>(membership); comm = communications.create(member, id, terminal, getClass().getCanonicalName(), r -> new GossiperServer(communications.getClientIdentityProvider(), metrics, r), getCreate(metrics), Gossiper.getLocalLoopback(member)); - ring = new SliceIterator("ChRbcGossip[%s on: %s]".formatted(id, member.getId()), member, membership, - comm); + ring = new SliceIterator<>("ChRbcGossip[%s on: %s]".formatted(id, member.getId()), member, membership, comm); } /** @@ -150,7 +145,7 @@ private Update gossipRound(Gossiper link) { if (!started.get()) { return null; } - log.trace("gossiping[{}] with {} on {}", id, link.getMember(), member); + log.trace("gossiping[{}] with {} on {}", id, link.getMember(), member.getId()); try { return link.gossip(processor.gossip(id)); } catch (StatusRuntimeException e) { diff --git a/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java b/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java index 74eb04de2..139d025b6 100644 --- a/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java +++ b/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java @@ -85,7 +85,7 @@ public class View { private static final String FINALIZE_VIEW_CHANGE = "FINALIZE VIEW CHANGE"; private static final Logger log = LoggerFactory.getLogger(View.class); private static final String SCHEDULED_VIEW_CHANGE = "Scheduled View Change"; - + final CommonCommunications comm; final AtomicBoolean started = new AtomicBoolean(); private final CommonCommunications approaches; @@ -343,8 +343,8 @@ void finalizeViewChange() { return; } viewChange(() -> { - final var superMajority = - context.size() == 1 ? 1 : context.getRingCount() - ((context.getRingCount() - 1) / 4); + var rings = context.getRingCount(); + final var superMajority = context.size() == 1 ? 1 : rings - ((rings - 1) / 4); if (observations.size() < superMajority) { log.trace("Do not have superMajority: {} required: {} observers: {} for: {} on: {}", observations.size(), superMajority, viewManagement.observersList(), currentView(), diff --git a/fireflies/src/main/java/com/salesforce/apollo/fireflies/ViewManagement.java b/fireflies/src/main/java/com/salesforce/apollo/fireflies/ViewManagement.java index 3104ab20d..2408ae7fc 100644 --- a/fireflies/src/main/java/com/salesforce/apollo/fireflies/ViewManagement.java +++ b/fireflies/src/main/java/com/salesforce/apollo/fireflies/ViewManagement.java @@ -374,6 +374,12 @@ boolean joined() { * start a view change if there are any offline members or joining members */ void maybeViewChange() { + if (context.size() == 1 && joins.size() < 3) { + log.info("Do not have minimum cluster size: {} required: {} for: {} on: {}", joins.size() + context.size(), + 4, currentView(), node.getId()); + view.scheduleViewChange(); + return; + } if ((context.offlineCount() > 0 || !joins.isEmpty())) { if (isObserver()) { log.trace("Initiating view change: {} (non observer) joins: {} leaves: {} on: {}", currentView(), diff --git a/memberships/src/main/java/com/salesforce/apollo/ring/RingIterator.java b/memberships/src/main/java/com/salesforce/apollo/ring/RingIterator.java index 6c42547b5..4ee531173 100644 --- a/memberships/src/main/java/com/salesforce/apollo/ring/RingIterator.java +++ b/memberships/src/main/java/com/salesforce/apollo/ring/RingIterator.java @@ -171,16 +171,17 @@ private void proceed(Digest key, final boolean allow, Runnable onMajority, Runna if (!finalIteration) { log.trace( "Determining: {} continuation of: {} for digest: {} tally: {} majority: {} final itr: {} allow: {} on: {}", - current, key, context.getId(), tally.get(), context.majority(), finalIteration, allow, member.getId()); + current, key, context.getId(), tally.get(), context.toleranceLevel() + 1, finalIteration, allow, + member.getId()); } if (finalIteration && allow) { log.trace("Completing iteration: {} of: {} for digest: {} tally: {} on: {}", iteration(), key, context.getId(), tally.get(), member.getId()); if (failedMajority != null && !majorityFailed) { - if (tally.get() < context.majority()) { + if (tally.get() < context.toleranceLevel() + 1) { majorityFailed = true; log.debug("Failed to obtain majority of: {} for digest: {} tally: {} required: {} on: {}", key, - context.getId(), tally.get(), context.majority(), member.getId()); + context.getId(), tally.get(), context.toleranceLevel() + 1, member.getId()); failedMajority.run(); } }