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: pr-unsubscr...@cassandra.apache.org
For additional commands, e-mail: pr-h...@cassandra.apache.org

Reply via email to