Github user jasobrown commented on a diff in the pull request:
https://github.com/apache/cassandra/pull/191#discussion_r168185310
--- Diff: src/java/org/apache/cassandra/net/MessagingService.java ---
@@ -1664,4 +1676,113 @@ public static boolean
isEncryptedConnection(InetAddressAndPort address)
}
return true;
}
+
+ public void blockForPeers()
+ {
+ // TODO make these yaml props?
+ int alivePercent = Integer.getInteger(Config.PROPERTY_PREFIX +
"blockForPeers.percent", 70);
+ if (alivePercent < 0)
+ alivePercent = 0;
+ else if (alivePercent > 100)
+ alivePercent = 100;
+
+ int aliveTimeoutSecs = Integer.getInteger(Config.PROPERTY_PREFIX +
"blockForPeers.timeout_in_secs", 10);
+ if (aliveTimeoutSecs < 0)
+ aliveTimeoutSecs = 1;
+ else if (aliveTimeoutSecs > 100)
+ aliveTimeoutSecs = 100;
+
+ if (alivePercent > 0)
+ blockForPeers(alivePercent, aliveTimeoutSecs);
+ }
+
+ private void blockForPeers(int targetAlivePercent, int
aliveTimeoutSecs)
+ {
+ // grab a snapshot of the current cluster from Gossiper. this is
completely prone to race conditions, but it's
+ // good enough for the purposes of blocking until some certain
percentage of nodes are considered 'alive'/connected.
+ Set<Map.Entry<InetAddressAndPort, EndpointState>> peers = new
HashSet<>(Gossiper.instance.getEndpointStates());
+
+ // remove current node from the set
+ peers = peers.stream()
+ .filter(entry ->
!entry.getKey().equals(FBUtilities.getBroadcastAddressAndPort()))
+ .collect(Collectors.toSet());
+
+ final int totalSize = peers.size();
+
+ // don't block if there's no other nodes in the cluster (or we
don't know about them)
+ if (totalSize <= 1)
+ return;
+
+ logger.info("choosing to block until {}% of peers are marked
alive; max time to wait = {} seconds", targetAlivePercent, aliveTimeoutSecs);
+
+ // first, send out a ping message to open up the non-gossip
connections
+ AtomicInteger connectedCount = sendPingMessages(peers);
--- End diff --
I thought about that, as well. I can force a message to go out on the large
message connection, but the `REQUEST_RESPONSE` will come back on the small
message connection. Unless, of course, I send some empty byte array that
exceeds the `OutboundMessagingPool#LARGE_MESSAGE_THRESHOLD`, [which is
currently
64k](https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/net/async/OutboundMessagingPool.java#L47).
Admittedly, I'm reticent to do that. I could, however, create variant of the
Ping/Pong messages (or modify those) to switch between either large or small
message connection.
I guess the concern i had was that many apps might not need the large
message connection, and thus it becomes unused, but consumed, resources. Every
instance will need the gossip and small message connections, but not every use
case calls for the large connections. wdyt?
---
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]