-
Notifications
You must be signed in to change notification settings - Fork 15
Optimize CassandraService node selection #6074
Changes from all commits
d59edd5
a6f6d4c
ae29ff0
2e97590
ff91ccc
cd752dc
a83f995
0301fa7
64dab73
8fa7811
1fa062c
6e88245
007e733
46ff7c4
2da2c1e
45aad23
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,13 +26,15 @@ | |
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
import javax.annotation.concurrent.GuardedBy; | ||
import org.immutables.value.Value; | ||
|
||
public final class CassandraAbsentHostTracker { | ||
private static final SafeLogger log = SafeLoggerFactory.get(CassandraAbsentHostTracker.class); | ||
|
||
private final int absenceLimit; | ||
|
||
@GuardedBy("this") | ||
private final Map<CassandraServer, PoolAndCount> absentCassandraServers; | ||
|
||
public CassandraAbsentHostTracker(int absenceLimit) { | ||
|
@@ -59,20 +61,20 @@ public synchronized void shutDown() { | |
absentCassandraServers.clear(); | ||
} | ||
|
||
private Set<CassandraServer> cleanupAbsentServer(Set<CassandraServer> absentServersSnapshot) { | ||
private ImmutableSet<CassandraServer> cleanupAbsentServer(ImmutableSet<CassandraServer> absentServersSnapshot) { | ||
absentServersSnapshot.forEach(this::incrementAbsenceCountIfPresent); | ||
return absentServersSnapshot.stream() | ||
.map(this::removeIfAbsenceThresholdReached) | ||
.flatMap(Optional::stream) | ||
.collect(Collectors.toSet()); | ||
.collect(ImmutableSet.toImmutableSet()); | ||
} | ||
|
||
private void incrementAbsenceCountIfPresent(CassandraServer cassandraServer) { | ||
private synchronized void incrementAbsenceCountIfPresent(CassandraServer cassandraServer) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good catch - I think this was deemed safe because it is only accessed by a single thread, but agree that guaranteeing this by adding synchronised is appropriate. |
||
absentCassandraServers.computeIfPresent( | ||
cassandraServer, (_host, poolAndCount) -> poolAndCount.incrementCount()); | ||
} | ||
|
||
private Optional<CassandraServer> removeIfAbsenceThresholdReached(CassandraServer cassandraServer) { | ||
private synchronized Optional<CassandraServer> removeIfAbsenceThresholdReached(CassandraServer cassandraServer) { | ||
if (absentCassandraServers.get(cassandraServer).timesAbsent() <= absenceLimit) { | ||
return Optional.empty(); | ||
} else { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -215,9 +215,8 @@ private static void createKeyspace(CassandraVerifierConfig verifierConfig) throw | |
} | ||
|
||
private static boolean attemptToCreateKeyspace(CassandraVerifierConfig verifierConfig) { | ||
Set<InetSocketAddress> thriftHosts = verifierConfig.servers().accept(new ThriftHostsExtractingVisitor()); | ||
|
||
return thriftHosts.stream().anyMatch(host -> attemptToCreateIfNotExists(host, verifierConfig)); | ||
return verifierConfig.servers().accept(ThriftHostsExtractingVisitor.INSTANCE).stream() | ||
.anyMatch(host -> attemptToCreateIfNotExists(host, verifierConfig)); | ||
Comment on lines
+218
to
+219
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no aversion whatsoever to this inlining, but is this a performance improvement or just a driveby? I'd be surprised if it was not the latter There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this was a drive by in-line because the switch to visitor singleton enum made this wrap, so just inlined it |
||
} | ||
|
||
private static boolean attemptToCreateIfNotExists(InetSocketAddress host, CassandraVerifierConfig verifierConfig) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to make the argument an
ImmutableSet
, no? The only annoying one is in the use ofgetRandomGoodHostForPredicate
- theSets.filter
should be an immutable result (since the input is immutable - at least, I assume that's how that works!) but I think we'd need to use anothercopyOf
to get the right type. Alternatively, if you reverted that back to a stream and usedImmutableSet.toImmutableSet()
we'd have the right types everywhere.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went back and forth if we wanted
ImmutableSet
in the public method args/return type, and could go either way. One of my intents with marking more of the private method returns withImmutableSet
andSetView
was to make it easier to reason about what it a point in time snapshot, and what may be lazily computed view.