@Override public CopycatException createException() { return new InternalException("internal Raft error"); } },
@Override public CopycatException createException() { return new InternalException("internal Raft error"); } },
@Override public CopycatException createException() { return new InternalException("internal Raft error"); } };
/** * Sets a commit time or fails the commit if a quorum of successful responses cannot be achieved. */ private void updateHeartbeatTime(MemberState member, Throwable error) { if (heartbeatFuture == null) { return; } if (error != null && member.getHeartbeatStartTime() == heartbeatTime) { int votingMemberSize = context.getClusterState().getActiveMemberStates().size() + (context.getCluster().member().type() == Member.Type.ACTIVE ? 1 : 0); int quorumSize = (int) Math.floor(votingMemberSize / 2) + 1; // If a quorum of successful responses cannot be achieved, fail this heartbeat. Ensure that only // ACTIVE members are considered. A member could have been transitioned to another state while the // heartbeat was being sent. if (member.getMember().type() == Member.Type.ACTIVE && ++heartbeatFailures > votingMemberSize - quorumSize) { heartbeatFuture.completeExceptionally(new InternalException("Failed to reach consensus")); completeHeartbeat(); } } else { member.setHeartbeatTime(System.currentTimeMillis()); // Sort the list of commit times. Use the quorum index to get the last time the majority of the cluster // was contacted. If the current heartbeatFuture's time is less than the commit time then trigger the // commit future and reset it to the next commit future. if (heartbeatTime <= heartbeatTime()) { heartbeatFuture.complete(null); completeHeartbeat(); } } }
/** * Sets a commit time or fails the commit if a quorum of successful responses cannot be achieved. */ private void updateHeartbeatTime(MemberState member, Throwable error) { if (heartbeatFuture == null) { return; } if (error != null && member.getHeartbeatStartTime() == heartbeatTime) { int votingMemberSize = context.getClusterState().getActiveMemberStates().size() + (context.getCluster().member().type() == Member.Type.ACTIVE ? 1 : 0); int quorumSize = (int) Math.floor(votingMemberSize / 2) + 1; // If a quorum of successful responses cannot be achieved, fail this heartbeat. Ensure that only // ACTIVE members are considered. A member could have been transitioned to another state while the // heartbeat was being sent. if (member.getMember().type() == Member.Type.ACTIVE && ++heartbeatFailures > votingMemberSize - quorumSize) { heartbeatFuture.completeExceptionally(new InternalException("Failed to reach consensus")); completeHeartbeat(); } } else { member.setHeartbeatTime(System.currentTimeMillis()); // Sort the list of commit times. Use the quorum index to get the last time the majority of the cluster // was contacted. If the current heartbeatFuture's time is less than the commit time then trigger the // commit future and reset it to the next commit future. if (heartbeatTime <= heartbeatTime()) { heartbeatFuture.complete(null); completeHeartbeat(); } } }
/** * Sets a commit time or fails the commit if a quorum of successful responses cannot be achieved. */ private void updateHeartbeatTime(MemberState member, Throwable error) { if (heartbeatFuture == null) { return; } if (error != null && member.getHeartbeatStartTime() == heartbeatTime) { int votingMemberSize = context.getClusterState().getActiveMemberStates().size() + (context.getCluster().member().type() == Member.Type.ACTIVE ? 1 : 0); int quorumSize = (int) Math.floor(votingMemberSize / 2) + 1; // If a quorum of successful responses cannot be achieved, fail this heartbeat. Ensure that only // ACTIVE members are considered. A member could have been transitioned to another state while the // heartbeat was being sent. if (member.getMember().type() == Member.Type.ACTIVE && ++heartbeatFailures > votingMemberSize - quorumSize) { heartbeatFuture.completeExceptionally(new InternalException("Failed to reach consensus")); completeHeartbeat(); } } else { member.setHeartbeatTime(System.currentTimeMillis()); // Sort the list of commit times. Use the quorum index to get the last time the majority of the cluster // was contacted. If the current heartbeatFuture's time is less than the commit time then trigger the // commit future and reset it to the next commit future. if (heartbeatTime <= heartbeatTime()) { heartbeatFuture.complete(null); completeHeartbeat(); } } }
/** * Applies an entry to the state machine. * <p> * Calls to this method are assumed to expect a result. This means linearizable session events * triggered by the application of the given entry will be awaited before completing the returned future. * * @param entry The entry to apply. * @return A completable future to be completed with the result. */ @SuppressWarnings("unchecked") public <T> CompletableFuture<T> apply(Entry entry) { LOGGER.trace("{} - Applying {}", state.getCluster().member().address(), entry); if (entry instanceof QueryEntry) { return (CompletableFuture<T>) apply((QueryEntry) entry); } else if (entry instanceof CommandEntry) { return (CompletableFuture<T>) apply((CommandEntry) entry); } else if (entry instanceof RegisterEntry) { return (CompletableFuture<T>) apply((RegisterEntry) entry); } else if (entry instanceof KeepAliveEntry) { return (CompletableFuture<T>) apply((KeepAliveEntry) entry); } else if (entry instanceof UnregisterEntry) { return (CompletableFuture<T>) apply((UnregisterEntry) entry); } else if (entry instanceof InitializeEntry) { return (CompletableFuture<T>) apply((InitializeEntry) entry); } else if (entry instanceof ConfigurationEntry) { return (CompletableFuture<T>) apply((ConfigurationEntry) entry); } return Futures.exceptionalFuture(new InternalException("unknown state machine operation")); }
/** * Applies an entry to the state machine. * <p> * Calls to this method are assumed to expect a result. This means linearizable session events * triggered by the application of the given entry will be awaited before completing the returned future. * * @param entry The entry to apply. * @return A completable future to be completed with the result. */ @SuppressWarnings("unchecked") public <T> CompletableFuture<T> apply(Entry entry) { LOGGER.trace("{} - Applying {}", state.getCluster().member().address(), entry); if (entry instanceof QueryEntry) { return (CompletableFuture<T>) apply((QueryEntry) entry); } else if (entry instanceof CommandEntry) { return (CompletableFuture<T>) apply((CommandEntry) entry); } else if (entry instanceof RegisterEntry) { return (CompletableFuture<T>) apply((RegisterEntry) entry); } else if (entry instanceof KeepAliveEntry) { return (CompletableFuture<T>) apply((KeepAliveEntry) entry); } else if (entry instanceof UnregisterEntry) { return (CompletableFuture<T>) apply((UnregisterEntry) entry); } else if (entry instanceof InitializeEntry) { return (CompletableFuture<T>) apply((InitializeEntry) entry); } else if (entry instanceof ConfigurationEntry) { return (CompletableFuture<T>) apply((ConfigurationEntry) entry); } return Futures.exceptionalFuture(new InternalException("unknown state machine operation")); }
/** * Applies an entry to the state machine. * * @param entry The entry to apply. * @param expectResult Indicates whether this call expects a result. * @return The result. */ private CompletableFuture<?> apply(Entry entry, boolean expectResult) { if (entry instanceof QueryEntry) { return apply((QueryEntry) entry); } else if (entry instanceof CommandEntry) { return apply((CommandEntry) entry, expectResult); } else if (entry instanceof RegisterEntry) { return apply((RegisterEntry) entry, expectResult); } else if (entry instanceof KeepAliveEntry) { return apply((KeepAliveEntry) entry); } else if (entry instanceof UnregisterEntry) { return apply((UnregisterEntry) entry, expectResult); } else if (entry instanceof InitializeEntry) { return apply((InitializeEntry) entry); } else if (entry instanceof ConnectEntry) { return apply((ConnectEntry) entry); } else if (entry instanceof ConfigurationEntry) { return apply((ConfigurationEntry) entry); } return Futures.exceptionalFuture(new InternalException("unknown state machine operation")); }