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 1a32112fb..e337a5dff 100644 --- a/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java +++ b/fireflies/src/main/java/com/salesforce/apollo/fireflies/View.java @@ -137,6 +137,7 @@ public View(DynamicContext context, ControlledIdentifierMember memb r -> new EntranceServer(gateway.getClientIdentityProvider(), r, metrics), EntranceClient.getCreate(metrics), Entrance.getLocalLoopback(node, service)); gossiper = new RingCommunications<>(context, node, comm); + gossiper.allowDuplicates(); this.validation = validation; this.verifiers = verifiers; } @@ -615,6 +616,7 @@ protected Gossip gossip(Fireflies link, int ring) { .setRing(ring) .setGossip(commonDigests()) .build()); + log.info("gossiping with: {} on: {}", link.getMember().getId(), node.getId()); try { return link.gossip(gossip); } catch (Throwable e) { @@ -1330,7 +1332,7 @@ private Gossip redirectTo(Participant member, int ring, Participant successor, D .setObservations(processObservations(BloomFilter.from(digests.getObservationBff()))) .setJoins(viewManagement.processJoins(BloomFilter.from(digests.getJoinBiff()))) .build(); - log.trace("Redirecting: {} to: {} on ring: {} notes: {} acc: {} obv: {} joins: {} on: {}", member.getId(), + log.trace("Redirect: {} to: {} on ring: {} notes: {} acc: {} obv: {} joins: {} on: {}", member.getId(), successor.getId(), ring, gossip.getNotes().getUpdatesCount(), gossip.getAccusations().getUpdatesCount(), gossip.getObservations().getUpdatesCount(), gossip.getJoins().getUpdatesCount(), node.getId()); @@ -1928,6 +1930,7 @@ public Gossip rumors(SayWhat request, Digest from) { final var digests = request.getGossip(); if (!successor.equals(node)) { g = redirectTo(member, ring, successor, digests); + log.info("Redirected: {} on: {}", member.getId(), node.getId()); } else { g = Gossip.newBuilder() .setNotes(processNotes(from, BloomFilter.from(digests.getNoteBff()), params.fpr())) diff --git a/fireflies/src/test/java/com/salesforce/apollo/fireflies/SwarmTest.java b/fireflies/src/test/java/com/salesforce/apollo/fireflies/SwarmTest.java index ddb713b19..5b1167d8d 100644 --- a/fireflies/src/test/java/com/salesforce/apollo/fireflies/SwarmTest.java +++ b/fireflies/src/test/java/com/salesforce/apollo/fireflies/SwarmTest.java @@ -180,6 +180,17 @@ public void swarm() throws Exception { } assertTrue(testGraph.isSC()); } + + var ringRef = views.get(0).getContext().rings().toList(); + for (var v : views) { + var tested = v.getContext().rings().toList(); + for (int i = 0; i < ringRef.size(); i++) { + var r = ringRef.get(i); + var t = tested.get(i); + assertEquals(r.getRing(), t.getRing()); + assertEquals(r.getRing(), t.getRing()); + } + } } communications.forEach(e -> e.close(Duration.ofSeconds(1))); views.forEach(view -> view.stop()); diff --git a/memberships/src/main/java/com/salesforce/apollo/context/DynamicContextImpl.java b/memberships/src/main/java/com/salesforce/apollo/context/DynamicContextImpl.java index fe6a7d963..fb080008a 100644 --- a/memberships/src/main/java/com/salesforce/apollo/context/DynamicContextImpl.java +++ b/memberships/src/main/java/com/salesforce/apollo/context/DynamicContextImpl.java @@ -16,6 +16,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import java.util.function.Predicate; @@ -41,7 +42,7 @@ public class DynamicContextImpl implements DynamicContext { private final Map> members = new ConcurrentSkipListMap<>(); private final Map> membershipListeners = new ConcurrentHashMap<>(); private final double pByz; - private final List> rings = new ArrayList<>(); + private final List> rings = new CopyOnWriteArrayList<>(); private volatile int cardinality; public DynamicContextImpl(Digest id, int cardinality, double pbyz, int bias) { @@ -526,7 +527,7 @@ public void rebalance(int newCardinality) { }); } assert rings.size() == ringCount : "Ring count: " + rings.size() + " does not match: " + ringCount; - log.debug("Rebalanced: {} from: {} to: {} tolerance: {}", id, currentCount, rings.size(), toleranceLevel()); + log.info("Rebalanced: {} from: {} to: {} tolerance: {}", id, currentCount, rings.size(), toleranceLevel()); } @Override