public boolean getPermits ( long permits ) throws InterruptedException { if ( permits <= 0 ) { return true ; } long startTimeNanos = System . nanoTime ( ) ; this . permitsOutstanding . addEntryWithWeight ( permits ) ; this . lock . lock ( ) ; try { while ( true ) { if ( permits >= this . knownUnsatisfiablePermits ) { // We are requesting more permits than the remote policy will ever be able to satisfy, return immediately with no permits break ; } if ( elapsedMillis ( startTimeNanos ) > this . maxTimeout ) { // Max timeout reached, break break ; } if ( this . permitBatchContainer . tryTake ( permits ) ) { this . permitsOutstanding . removeEntryWithWeight ( permits ) ; return true ; } if ( this . retryStatus . canRetryWithinMillis ( remainingTime ( startTimeNanos , this . maxTimeout ) ) ) { long callbackCounterSnap = this . callbackCounter . get ( ) ; maybeSendNewPermitRequest ( ) ; if ( this . callbackCounter . get ( ) == callbackCounterSnap ) { // If a callback has happened since we tried to send the new permit request, don't await // Since some request senders may be synchronous, we would have missed the notification boolean ignore = this . newPermitsAvailable . await ( remainingTime ( startTimeNanos , this . maxTimeout ) , TimeUnit . MILLISECONDS ) ; } } else { break ; } } } finally { this . lock . unlock ( ) ; } this . permitsOutstanding . removeEntryWithWeight ( permits ) ; return false ; }
Try to get a number of permits from this requester .