From a2c3a9f52c6f58c697c373f7b6d9d1b5da42f2fa Mon Sep 17 00:00:00 2001 From: Hellblazer Date: Mon, 10 Jun 2024 18:23:12 -0700 Subject: [PATCH] use tolerance + 1 for majority, rather than 2/3+1 in DHT/iterations. --- .../com/salesforce/apollo/fireflies/View.java | 52 +++++++++---------- .../salesforce/apollo/ring/RingIterator.java | 2 +- .../com/salesforce/apollo/thoth/KerlDHT.java | 10 ++-- 3 files changed, 32 insertions(+), 32 deletions(-) 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 b8f0c2f83..74eb04de2 100644 --- a/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java +++ b/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java @@ -82,34 +82,34 @@ * @since 220 */ 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; - private final DynamicContext context; - private final DigestAlgorithm digestAlgo; - private final RingCommunications gossiper; - private final AtomicBoolean introduced = new AtomicBoolean(); - private final List> viewChangeListeners = new CopyOnWriteArrayList<>(); - private final Executor viewNotificationQueue = Executors.newSingleThreadExecutor( + 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; + private final DynamicContext context; + private final DigestAlgorithm digestAlgo; + private final RingCommunications gossiper; + private final AtomicBoolean introduced = new AtomicBoolean(); + private final List> viewChangeListeners = new CopyOnWriteArrayList<>(); + private final Executor viewNotificationQueue = Executors.newSingleThreadExecutor( Thread.ofVirtual().factory()); - private final FireflyMetrics metrics; - private final Node node; - private final Map observations = new ConcurrentSkipListMap<>(); - private final Parameters params; - private final ConcurrentMap pendingRebuttals = new ConcurrentSkipListMap<>(); - private final RoundScheduler roundTimers; - private final Set shunned = new ConcurrentSkipListSet<>(); - private final Map timers = new HashMap<>(); - private final ReadWriteLock viewChange = new ReentrantReadWriteLock( + private final FireflyMetrics metrics; + private final Node node; + private final Map observations = new ConcurrentSkipListMap<>(); + private final Parameters params; + private final ConcurrentMap pendingRebuttals = new ConcurrentSkipListMap<>(); + private final RoundScheduler roundTimers; + private final Set shunned = new ConcurrentSkipListSet<>(); + private final Map timers = new HashMap<>(); + private final ReadWriteLock viewChange = new ReentrantReadWriteLock( true); - private final ViewManagement viewManagement; - private final EventValidation validation; - private final Verifiers verifiers; - private volatile ScheduledFuture futureGossip; + private final ViewManagement viewManagement; + private final EventValidation validation; + private final Verifiers verifiers; + private volatile ScheduledFuture futureGossip; public View(DynamicContext context, ControlledIdentifierMember member, String endpoint, EventValidation validation, Verifiers verifiers, Router communications, Parameters params, 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 c582c09e3..6c42547b5 100644 --- a/memberships/src/main/java/com/salesforce/apollo/ring/RingIterator.java +++ b/memberships/src/main/java/com/salesforce/apollo/ring/RingIterator.java @@ -192,7 +192,7 @@ private void proceed(Digest key, final boolean allow, Runnable onMajority, Runna member.getId()); } else { if (onMajority != null && !majoritySucceed) { - if (tally.get() >= context.majority()) { + if (tally.get() > context.toleranceLevel()) { majoritySucceed = true; log.debug("Obtained: {} majority of: {} for digest: {} tally: {} on: {}", current, key, context.getId(), tally.get(), member.getId()); diff --git a/thoth/src/main/java/com/salesforce/apollo/thoth/KerlDHT.java b/thoth/src/main/java/com/salesforce/apollo/thoth/KerlDHT.java index 1939e0a47..d816b0838 100644 --- a/thoth/src/main/java/com/salesforce/apollo/thoth/KerlDHT.java +++ b/thoth/src/main/java/com/salesforce/apollo/thoth/KerlDHT.java @@ -778,7 +778,7 @@ private void completeIt(CompletableFuture result, HashMultiset gathere .stream() .max(Ordering.natural().onResultOf(Multiset.Entry::getCount)) .orElse(null); - var majority = context.size() == 1 ? 1 : context.majority(); + var majority = context.size() == 1 ? 1 : context.toleranceLevel() + 1; if (max != null) { if (max.getCount() >= majority) { try { @@ -796,10 +796,10 @@ private void completeIt(CompletableFuture result, HashMultiset gathere private boolean failedMajority(CompletableFuture result, int maxAgree, String operation) { log.debug("Unable to achieve majority read: {}, max: {} required: {} on: {}", operation, maxAgree, - context.majority(), member.getId()); + context.toleranceLevel() + 1, member.getId()); return result.completeExceptionally(new CompletionException( - "Unable to achieve majority read: " + operation + ", max: " + maxAgree + " required: " + context.majority() - + " on: " + member.getId())); + "Unable to achieve majority read: " + operation + ", max: " + maxAgree + " required: " + + context.toleranceLevel() + 1 + " on: " + member.getId())); } private void initializeSchema() { @@ -877,7 +877,7 @@ private boolean read(CompletableFuture result, HashMultiset gathered, var max = max(gathered); if (max != null) { tally.set(max.getCount()); - var ctxMajority = context.size() == 1 ? 1 : context.majority(); + var ctxMajority = context.size() == 1 ? 1 : context.toleranceLevel() + 1; final var majority = tally.get() >= ctxMajority; if (majority) { result.complete(max.getElement());