
rocks.xmpp.core.session.TruncatedBinaryExponentialBackoffStrategy Maven / Gradle / Ivy
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2016 Christian Schudt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package rocks.xmpp.core.session;
import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
/**
* This is the default reconnection strategy used by the {@link rocks.xmpp.core.session.ReconnectionManager}.
*
* It exponentially increases the time span from which a random value for the next reconnection attempt is chosen.
* The formula for doing this, is: (2n - 1) * s
, where n
is the number of reconnection attempt and s
is the slot time, which is 60 seconds by default.
*
* In practice this means, the first reconnection attempt occurs after a random period of time between 0 and 60 seconds.
* The second attempt chooses a random number >= 0 and < 180 seconds.
* The third attempt chooses a random number >= 0 and < 420 seconds.
* The fourth attempt chooses a random number >= 0 and < 900 seconds.
* The fifth attempt chooses a random number >= 0 and < 1860 seconds (= 31 minutes)
*
* The strategy is called "truncated", because it won't increase the time span after the nth iteration, which means in the example above, the sixth and any further attempt
* behaves equally to the fifth attempt.
*
* This "truncated binary exponential backoff" is the recommended reconnection strategy by the XMPP specification.
*
* This class is immutable.
*
* @author Christian Schudt
* @see rocks.xmpp.core.session.ReconnectionManager#setReconnectionStrategy(ReconnectionStrategy)
*/
class TruncatedBinaryExponentialBackoffStrategy implements ReconnectionStrategy {
private final int slotTime;
private final int ceiling;
/**
* @param slotTime The slot time (in seconds), usually 60.
* @param ceiling The ceiling, i.e. when the time is truncated. E.g. if the ceiling is 4, the back off is truncated at the 5th reconnection attempt (it starts at zero).
*/
TruncatedBinaryExponentialBackoffStrategy(int slotTime, int ceiling) {
this.slotTime = slotTime;
this.ceiling = ceiling;
}
@Override
public Duration getNextReconnectionAttempt(int attempt, Throwable throwable) {
// For the first attempt choose a random number between 0 and 60.
// For the second attempt choose a random number between 0 and 180.
// For the third attempt choose a random number between 0 and 420.
// For the fourth attempt choose a random number between 0 and 900.
// For the fifth attempt choose a random number between 0 and 1860.
// ==> max wait time: 1860 seconds = 31 minutes. (if ceiling == 5)
return Duration.ofSeconds(ThreadLocalRandom.current().nextInt((int) (Math.pow(2, Math.min(attempt, ceiling) + 1) - 1) * slotTime));
}
}