All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rocks.xmpp.core.session.ReconnectionStrategy Maven / Gradle / Ivy

There is a newer version: 0.9.1
Show newest version
/*
 * 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 rocks.xmpp.core.stream.StreamErrorException;
import rocks.xmpp.core.stream.model.errors.Condition;

import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * A strategy for reconnection logic, i.e. when and in which interval reconnection attempts will happen. You can provide your own strategy by implementing this interface.
 * 

* Alternatively you can use some of the predefined strategies which you can retrieve by one of the static methods. *

* E.g. {@link #after(long, TimeUnit)} always tries to reconnect after a fix amount of time. * * @author Christian Schudt * @see ReconnectionManager#setReconnectionStrategy(ReconnectionStrategy) */ @FunctionalInterface public interface ReconnectionStrategy { default boolean mayReconnect(int attempt, Throwable e) { // By default allow reconnection only if it's not caused by a stream error. return !(e instanceof StreamErrorException) || ((StreamErrorException) e).getCondition() != Condition.CONFLICT; } /** * Gets the duration after which the next reconnection is attempted. * * @param attempt The current reconnection attempt. The first attempt is 0, the second attempt is 1, etc... * @param cause The cause for the disconnection. * @return The the duration after which the next reconnection is attempted. */ Duration getNextReconnectionAttempt(int attempt, Throwable cause); /** * 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. * * @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). * @return The truncated binary exponential backoff strategy. */ static ReconnectionStrategy truncatedBinaryExponentialBackoffStrategy(int slotTime, int ceiling) { return new TruncatedBinaryExponentialBackoffStrategy(slotTime, ceiling); } /** * Reconnects always after a fix duration, e.g. after 10 seconds. * * @param duration The fix duration after which a reconnection is attempted. * @param timeUnit The time unit. * @return The reconnection strategy. * @deprecated Use {@link #alwaysAfter(Duration)} */ @Deprecated static ReconnectionStrategy after(long duration, TimeUnit timeUnit) { return (attempt, cause) -> Duration.ofSeconds(timeUnit.toSeconds(duration)); } /** * Reconnects always after a fix duration, e.g. after 10 seconds. When a disconnection is detected the first reconnection attempt is started after the given duration. * If the attempt fails, the second one is started again after the same duration and so on. * * @param duration The fix duration after which a reconnection is attempted. * @return The reconnection strategy. */ static ReconnectionStrategy alwaysAfter(Duration duration) { return (attempt, cause) -> duration; } /** * Reconnects always after a random duration which lies between the given min and max duration, e.g. after 10-20 seconds. * * @param min The min duration after which a reconnection is attempted. * @param max The max duration. * @return The reconnection strategy. */ static ReconnectionStrategy alwaysRandomlyAfter(Duration min, Duration max) { return (attempt, cause) -> Duration.ofSeconds(ThreadLocalRandom.current().nextLong(min.getSeconds(), max.getSeconds())); } /** * Uses a hybrid reconnection strategy, which uses the first one on system shutdown and the second one on every other disconnection cause. * * @param first The first strategy. * @param second The second strategy. * @return The reconnection strategy. */ static ReconnectionStrategy onSystemShutdownFirstOrElseSecond(ReconnectionStrategy first, ReconnectionStrategy second) { return new HybridReconnectionStrategy(first, second, new ReconnectionManager.SystemShutdownPredicate()); } /** * Reconnection won't happen automatically, i.e. it's disabled. * * @return The reconnection strategy. */ static ReconnectionStrategy none() { return new ReconnectionStrategy() { @Override public boolean mayReconnect(int attempt, Throwable cause) { return false; } @Override public Duration getNextReconnectionAttempt(int attempt, Throwable cause) { return Duration.ZERO; } }; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy