public PermitsAndDelay getPermitsAndDelay ( long requestedPermits , long minPermits , long timeoutMillis ) { try { long storedTokens = this . tokenBucket . getStoredTokens ( ) ; long eagerTokens = storedTokens / 2 ; if ( eagerTokens > requestedPermits && this . tokenBucket . getTokens ( eagerTokens , 0 , TimeUnit . MILLISECONDS ) ) { return new PermitsAndDelay ( eagerTokens , 0 , true ) ; } long millisToSatisfyMinPermits = ( long ) ( minPermits / this . tokenBucket . getTokensPerMilli ( ) ) ; if ( millisToSatisfyMinPermits > timeoutMillis ) { return new PermitsAndDelay ( 0 , 0 , false ) ; } long allowedTimeout = Math . min ( millisToSatisfyMinPermits + this . baseTimeout , timeoutMillis ) ; while ( requestedPermits > minPermits ) { long wait = this . tokenBucket . tryReserveTokens ( requestedPermits , allowedTimeout ) ; if ( wait >= 0 ) { return new PermitsAndDelay ( requestedPermits , wait , true ) ; } requestedPermits /= 2 ; } long wait = this . tokenBucket . tryReserveTokens ( minPermits , allowedTimeout ) ; if ( wait >= 0 ) { return new PermitsAndDelay ( requestedPermits , wait , true ) ; } } catch ( InterruptedException ie ) { // Fallback to returning 0 } return new PermitsAndDelay ( 0 , 0 , true ) ; }
Request tokens .