private CompletableFuture < Void > throttle ( ) { val delay = new AtomicReference < ThrottlerCalculator . DelayResult > ( this . throttlerCalculator . getThrottlingDelay ( ) ) ; if ( ! delay . get ( ) . isMaximum ( ) ) { // We are not delaying the maximum amount. We only need to do this once. return throttleOnce ( delay . get ( ) . getDurationMillis ( ) , delay . get ( ) . isMaximum ( ) ) ; } else { // The initial delay calculation indicated that we need to throttle to the maximum, which means there's // significant pressure. In order to protect downstream components, we need to run in a loop and delay as much // as needed until the pressure is relieved. return Futures . loop ( ( ) -> ! delay . get ( ) . isMaximum ( ) , ( ) -> throttleOnce ( delay . get ( ) . getDurationMillis ( ) , delay . get ( ) . isMaximum ( ) ) . thenRun ( ( ) -> delay . set ( this . throttlerCalculator . getThrottlingDelay ( ) ) ) , this . executor ) ; } }
region Queue Processing