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);
}
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;
}
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;
}
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);
}
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);
}
}
});
}
Aggregations