private void sendOneAsyncHint ( final ByteArray slopKey , final Versioned < byte [ ] > slopVersioned , final List < Node > nodesToTry ) { Node nodeToHostHint = null ; boolean foundNode = false ; while ( nodesToTry . size ( ) > 0 ) { nodeToHostHint = nodesToTry . remove ( 0 ) ; if ( ! failedNodes . contains ( nodeToHostHint ) && failureDetector . isAvailable ( nodeToHostHint ) ) { foundNode = true ; break ; } } if ( ! foundNode ) { Slop slop = slopSerializer . toObject ( slopVersioned . getValue ( ) ) ; logger . error ( "Trying to send an async hint but used up all nodes. key: " + slop . getKey ( ) + " version: " + slopVersioned . getVersion ( ) . toString ( ) ) ; return ; } final Node node = nodeToHostHint ; int nodeId = node . getId ( ) ; NonblockingStore nonblockingStore = nonblockingSlopStores . get ( nodeId ) ; Utils . notNull ( nonblockingStore ) ; final Long startNs = System . nanoTime ( ) ; NonblockingStoreCallback callback = new NonblockingStoreCallback ( ) { @ Override public void requestComplete ( Object result , long requestTime ) { Slop slop = null ; boolean loggerDebugEnabled = logger . isDebugEnabled ( ) ; if ( loggerDebugEnabled ) { slop = slopSerializer . toObject ( slopVersioned . getValue ( ) ) ; } Response < ByteArray , Object > response = new Response < ByteArray , Object > ( node , slopKey , result , requestTime ) ; if ( response . getValue ( ) instanceof Exception && ! ( response . getValue ( ) instanceof ObsoleteVersionException ) ) { if ( ! failedNodes . contains ( node ) ) failedNodes . add ( node ) ; if ( response . getValue ( ) instanceof UnreachableStoreException ) { UnreachableStoreException use = ( UnreachableStoreException ) response . getValue ( ) ; if ( loggerDebugEnabled ) { logger . debug ( "Write of key " + slop . getKey ( ) + " for " + slop . getNodeId ( ) + " to node " + node + " failed due to unreachable: " + use . getMessage ( ) ) ; } failureDetector . recordException ( node , ( System . nanoTime ( ) - startNs ) / Time . NS_PER_MS , use ) ; } sendOneAsyncHint ( slopKey , slopVersioned , nodesToTry ) ; } if ( loggerDebugEnabled ) logger . debug ( "Slop write of key " + slop . getKey ( ) + " for node " + slop . getNodeId ( ) + " to node " + node + " succeeded in " + ( System . nanoTime ( ) - startNs ) + " ns" ) ; failureDetector . recordSuccess ( node , ( System . nanoTime ( ) - startNs ) / Time . NS_PER_MS ) ; } } ; nonblockingStore . submitPutRequest ( slopKey , slopVersioned , null , callback , timeoutMs ) ; }
A callback that handles requestComplete event from NIO selector manager Will try any possible nodes and pass itself as callback util all nodes are exhausted