Search in sources :

Example 1 with KeepAliveRequest

use of io.atomix.protocols.raft.protocol.KeepAliveRequest in project atomix by atomix.

the class RaftProxyManager method resetAllIndexes.

/**
 * Resets indexes for all sessions.
 */
private synchronized void resetAllIndexes() {
    Collection<RaftProxyState> sessions = Lists.newArrayList(this.sessions.values());
    // Allocate session IDs, command response sequence numbers, and event index arrays.
    long[] sessionIds = new long[sessions.size()];
    long[] commandResponses = new long[sessions.size()];
    long[] eventIndexes = new long[sessions.size()];
    // For each session that needs to be kept alive, populate batch request arrays.
    int i = 0;
    for (RaftProxyState sessionState : sessions) {
        sessionIds[i] = sessionState.getSessionId().id();
        commandResponses[i] = sessionState.getCommandResponse();
        eventIndexes[i] = sessionState.getEventIndex();
        i++;
    }
    log.trace("Resetting {} sessions", sessionIds.length);
    KeepAliveRequest request = KeepAliveRequest.builder().withSessionIds(sessionIds).withCommandSequences(commandResponses).withEventIndexes(eventIndexes).build();
    connection.keepAlive(request);
}
Also used : KeepAliveRequest(io.atomix.protocols.raft.protocol.KeepAliveRequest)

Example 2 with KeepAliveRequest

use of io.atomix.protocols.raft.protocol.KeepAliveRequest in project atomix by atomix.

the class RaftProxyManager method resetIndexes.

/**
 * Resets indexes for the given session.
 *
 * @param sessionId The session for which to reset indexes.
 * @return A completable future to be completed once the session's indexes have been reset.
 */
CompletableFuture<Void> resetIndexes(SessionId sessionId) {
    RaftProxyState sessionState = sessions.get(sessionId.id());
    if (sessionState == null) {
        return Futures.exceptionalFuture(new IllegalArgumentException("Unknown session: " + sessionId));
    }
    CompletableFuture<Void> future = new CompletableFuture<>();
    KeepAliveRequest request = KeepAliveRequest.builder().withSessionIds(new long[] { sessionId.id() }).withCommandSequences(new long[] { sessionState.getCommandResponse() }).withEventIndexes(new long[] { sessionState.getEventIndex() }).build();
    connection.keepAlive(request).whenComplete((response, error) -> {
        if (error == null) {
            if (response.status() == RaftResponse.Status.OK) {
                future.complete(null);
            } else {
                future.completeExceptionally(response.error().createException());
            }
        } else {
            future.completeExceptionally(error);
        }
    });
    return future;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) KeepAliveRequest(io.atomix.protocols.raft.protocol.KeepAliveRequest)

Example 3 with KeepAliveRequest

use of io.atomix.protocols.raft.protocol.KeepAliveRequest in project atomix by atomix.

the class RaftSessionManager method resetIndexes.

/**
 * Resets indexes for the given session.
 *
 * @param sessionId The session for which to reset indexes.
 * @return A completable future to be completed once the session's indexes have been reset.
 */
CompletableFuture<Void> resetIndexes(SessionId sessionId) {
    RaftSessionState sessionState = sessions.get(sessionId.id());
    if (sessionState == null) {
        return Futures.exceptionalFuture(new IllegalArgumentException("Unknown session: " + sessionId));
    }
    CompletableFuture<Void> future = new CompletableFuture<>();
    KeepAliveRequest request = KeepAliveRequest.builder().withSessionIds(new long[] { sessionId.id() }).withCommandSequences(new long[] { sessionState.getCommandResponse() }).withEventIndexes(new long[] { sessionState.getEventIndex() }).build();
    connection.keepAlive(request).whenComplete((response, error) -> {
        if (error == null) {
            if (response.status() == RaftResponse.Status.OK) {
                future.complete(null);
            } else {
                future.completeExceptionally(response.error().createException());
            }
        } else {
            future.completeExceptionally(error);
        }
    });
    return future;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) KeepAliveRequest(io.atomix.protocols.raft.protocol.KeepAliveRequest)

Example 4 with KeepAliveRequest

use of io.atomix.protocols.raft.protocol.KeepAliveRequest in project atomix by atomix.

the class RaftSessionManager method resetAllIndexes.

/**
 * Resets indexes for all sessions.
 */
private synchronized void resetAllIndexes() {
    Collection<RaftSessionState> sessions = Lists.newArrayList(this.sessions.values());
    // If no sessions are open, skip the keep-alive.
    if (sessions.isEmpty()) {
        return;
    }
    // Allocate session IDs, command response sequence numbers, and event index arrays.
    long[] sessionIds = new long[sessions.size()];
    long[] commandResponses = new long[sessions.size()];
    long[] eventIndexes = new long[sessions.size()];
    // For each session that needs to be kept alive, populate batch request arrays.
    int i = 0;
    for (RaftSessionState sessionState : sessions) {
        sessionIds[i] = sessionState.getSessionId().id();
        commandResponses[i] = sessionState.getCommandResponse();
        eventIndexes[i] = sessionState.getEventIndex();
        i++;
    }
    log.trace("Resetting {} sessions", sessionIds.length);
    KeepAliveRequest request = KeepAliveRequest.builder().withSessionIds(sessionIds).withCommandSequences(commandResponses).withEventIndexes(eventIndexes).build();
    connection.keepAlive(request);
}
Also used : KeepAliveRequest(io.atomix.protocols.raft.protocol.KeepAliveRequest)

Example 5 with KeepAliveRequest

use of io.atomix.protocols.raft.protocol.KeepAliveRequest in project atomix by atomix.

the class RaftProxyManager method keepAliveSessions.

/**
 * Sends a keep-alive request to the cluster.
 */
private synchronized void keepAliveSessions(long lastKeepAliveTime, long sessionTimeout) {
    // Filter the list of sessions by timeout.
    List<RaftProxyState> needKeepAlive = sessions.values().stream().filter(session -> session.getSessionTimeout() == sessionTimeout).collect(Collectors.toList());
    // If no sessions need keep-alives to be sent, skip and reschedule the keep-alive.
    if (needKeepAlive.isEmpty()) {
        return;
    }
    // Allocate session IDs, command response sequence numbers, and event index arrays.
    long[] sessionIds = new long[needKeepAlive.size()];
    long[] commandResponses = new long[needKeepAlive.size()];
    long[] eventIndexes = new long[needKeepAlive.size()];
    // For each session that needs to be kept alive, populate batch request arrays.
    int i = 0;
    for (RaftProxyState sessionState : needKeepAlive) {
        sessionIds[i] = sessionState.getSessionId().id();
        commandResponses[i] = sessionState.getCommandResponse();
        eventIndexes[i] = sessionState.getEventIndex();
        i++;
    }
    log.trace("Keeping {} sessions alive", sessionIds.length);
    KeepAliveRequest request = KeepAliveRequest.builder().withSessionIds(sessionIds).withCommandSequences(commandResponses).withEventIndexes(eventIndexes).build();
    long keepAliveTime = System.currentTimeMillis();
    connection.keepAlive(request).whenComplete((response, error) -> {
        if (open.get()) {
            long delta = System.currentTimeMillis() - keepAliveTime;
            if (error == null) {
                // If the request was successful, update the address selector and schedule the next keep-alive.
                if (response.status() == RaftResponse.Status.OK) {
                    selectorManager.resetAll(response.leader(), response.members());
                    // Iterate through sessions and close sessions that weren't kept alive by the request (have already been closed).
                    Set<Long> keptAliveSessions = Sets.newHashSet(Longs.asList(response.sessionIds()));
                    for (RaftProxyState session : needKeepAlive) {
                        if (keptAliveSessions.contains(session.getSessionId().id())) {
                            session.setState(PrimitiveProxy.State.CONNECTED);
                        } else {
                            session.setState(PrimitiveProxy.State.CLOSED);
                        }
                    }
                    scheduleKeepAlive(System.currentTimeMillis(), sessionTimeout, delta);
                } else // We will continue to retry until the session expiration has passed.
                if (System.currentTimeMillis() - lastKeepAliveTime < sessionTimeout) {
                    selectorManager.resetAll(null, connection.members());
                    keepAliveSessions(lastKeepAliveTime, sessionTimeout);
                } else // If no leader was set, set the session state to unstable and schedule another keep-alive.
                {
                    needKeepAlive.forEach(s -> s.setState(PrimitiveProxy.State.SUSPENDED));
                    selectorManager.resetAll();
                    scheduleKeepAlive(lastKeepAliveTime, sessionTimeout, delta);
                }
            } else // again with no delay.
            if (System.currentTimeMillis() - lastKeepAliveTime < sessionTimeout && connection.leader() != null) {
                selectorManager.resetAll(null, connection.members());
                keepAliveSessions(lastKeepAliveTime, sessionTimeout);
            } else // If no leader was set, set the session state to unstable and schedule another keep-alive.
            {
                needKeepAlive.forEach(s -> s.setState(PrimitiveProxy.State.SUSPENDED));
                selectorManager.resetAll();
                scheduleKeepAlive(lastKeepAliveTime, sessionTimeout, delta);
            }
        }
    });
}
Also used : NodeId(io.atomix.cluster.NodeId) RaftClient(io.atomix.protocols.raft.RaftClient) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) CloseSessionRequest(io.atomix.protocols.raft.protocol.CloseSessionRequest) ContextualLoggerFactory(io.atomix.utils.logging.ContextualLoggerFactory) RaftClientProtocol(io.atomix.protocols.raft.protocol.RaftClientProtocol) SessionId(io.atomix.primitive.session.SessionId) Lists(com.google.common.collect.Lists) RaftResponse(io.atomix.protocols.raft.protocol.RaftResponse) Duration(java.time.Duration) Map(java.util.Map) Scheduled(io.atomix.utils.concurrent.Scheduled) Futures(io.atomix.utils.concurrent.Futures) Longs(com.google.common.primitives.Longs) HeartbeatRequest(io.atomix.protocols.raft.protocol.HeartbeatRequest) Logger(org.slf4j.Logger) LoggerContext(io.atomix.utils.logging.LoggerContext) HeartbeatResponse(io.atomix.protocols.raft.protocol.HeartbeatResponse) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Set(java.util.Set) ReadConsistency(io.atomix.protocols.raft.ReadConsistency) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) ThreadContext(io.atomix.utils.concurrent.ThreadContext) OpenSessionRequest(io.atomix.protocols.raft.protocol.OpenSessionRequest) ThreadContextFactory(io.atomix.utils.concurrent.ThreadContextFactory) Objects(java.util.Objects) List(java.util.List) KeepAliveRequest(io.atomix.protocols.raft.protocol.KeepAliveRequest) PrimitiveProxy(io.atomix.primitive.proxy.PrimitiveProxy) PrimitiveType(io.atomix.primitive.PrimitiveType) CommunicationStrategy(io.atomix.protocols.raft.proxy.CommunicationStrategy) RaftException(io.atomix.protocols.raft.RaftException) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) KeepAliveRequest(io.atomix.protocols.raft.protocol.KeepAliveRequest)

Aggregations

KeepAliveRequest (io.atomix.protocols.raft.protocol.KeepAliveRequest)6 CompletableFuture (java.util.concurrent.CompletableFuture)4 MoreObjects.toStringHelper (com.google.common.base.MoreObjects.toStringHelper)2 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)2 Lists (com.google.common.collect.Lists)2 Sets (com.google.common.collect.Sets)2 Longs (com.google.common.primitives.Longs)2 PrimitiveType (io.atomix.primitive.PrimitiveType)2 SessionId (io.atomix.primitive.session.SessionId)2 RaftClient (io.atomix.protocols.raft.RaftClient)2 RaftException (io.atomix.protocols.raft.RaftException)2 ReadConsistency (io.atomix.protocols.raft.ReadConsistency)2 CloseSessionRequest (io.atomix.protocols.raft.protocol.CloseSessionRequest)2 HeartbeatRequest (io.atomix.protocols.raft.protocol.HeartbeatRequest)2 HeartbeatResponse (io.atomix.protocols.raft.protocol.HeartbeatResponse)2 OpenSessionRequest (io.atomix.protocols.raft.protocol.OpenSessionRequest)2 RaftClientProtocol (io.atomix.protocols.raft.protocol.RaftClientProtocol)2 RaftResponse (io.atomix.protocols.raft.protocol.RaftResponse)2 Futures (io.atomix.utils.concurrent.Futures)2 Scheduled (io.atomix.utils.concurrent.Scheduled)2