import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.raft.persisted.Snapshot;
+import org.opendaylight.controller.cluster.raft.spi.LogEntry;
import org.opendaylight.raft.api.EntryMeta;
/**
* Appends an entry received by a follower to the in-memory log and persists it as well, returning an indication
* whether or not a snapshot should be taken.
*
- * @param <T> entry type
* @param entry the entry to append
* @param callback optional callback to be notified when persistence is complete
* @return {@code true} if the journal requires trimming and a snapshot needs to be taken
*/
- <T extends ReplicatedLogEntry> boolean appendReceived(@NonNull T entry, @Nullable Consumer<T> callback);
+ @NonNullByDefault
+ boolean appendReceived(ReplicatedLogEntry entry, @Nullable Consumer<LogEntry> callback);
/**
* Appends an entry submitted on the leader to the in-memory log and persists it as well.
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.raft.persisted.DeleteEntries;
+import org.opendaylight.controller.cluster.raft.spi.LogEntry;
import org.opendaylight.raft.api.EntryMeta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
@Override
- public <T extends ReplicatedLogEntry> boolean appendReceived(final T entry, final Consumer<T> callback) {
+ public boolean appendReceived(final ReplicatedLogEntry entry, final Consumer<LogEntry> callback) {
LOG.debug("{}: Append log entry and persist {} ", memberId, entry);
// FIXME: When can 'false' happen? Wouldn't that be an indication that Follower.handleAppendEntries() is doing
}
private <T extends ReplicatedLogEntry> void invokeSync(final @NonNull T entry,
- final @Nullable Consumer<T> callback) {
+ final @Nullable Consumer<? super T> callback) {
LOG.debug("{}: persist complete {}", memberId, entry);
dataSizeSinceLastSnapshot += entry.size();
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.controller.cluster.messaging.MessageAssembler;
import org.opendaylight.controller.cluster.raft.RaftActorContext;
-import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
import org.opendaylight.controller.cluster.raft.SnapshotManager.ApplyLeaderSnapshot;
import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout;
import org.opendaylight.controller.cluster.raft.base.messages.TimeoutNow;
// applied to the state already, as the persistence callback occurs async, and we want those entries
// purged from the persisted log as well.
final var shouldCaptureSnapshot = new AtomicBoolean(false);
- final Consumer<ReplicatedLogEntry> callback = logEntry -> {
+
+ // Note: this is quite fishy: while we are reusing this callback, the capture part of is only used for the
+ // last entry -- so we really should split the below loop into 'leading entries' with a 'null' callback
+ // and the last entry, with this callback.
+ // Furthermore the correctness of this relies on the fact that the callback is invoked asynchronously,
+ // i.e. in the next RaftActor processing cycle.
+ final Consumer<LogEntry> callback = logEntry -> {
if (shouldCaptureSnapshot.get() && logEntry == entries.getLast()) {
context.getSnapshotManager().capture(replLog.lastMeta(), getReplicatedToAllIndex());
}
import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry;
import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
+import org.opendaylight.controller.cluster.raft.spi.LogEntry;
import org.opendaylight.controller.cluster.raft.spi.TestTermInfoStore;
import org.opendaylight.raft.api.EntryMeta;
}
@Override
- public <T extends ReplicatedLogEntry> boolean appendReceived(final T entry, final Consumer<T> callback) {
+ public boolean appendReceived(final ReplicatedLogEntry entry, final Consumer<LogEntry> callback) {
// FIXME: assertion here?
append(entry);
if (callback != null) {
package org.opendaylight.controller.cluster.raft;
import java.util.function.Consumer;
+import org.opendaylight.controller.cluster.raft.spi.LogEntry;
import org.opendaylight.raft.api.EntryMeta;
final class MockReplicatedLog extends AbstractReplicatedLog {
}
@Override
- public <T extends ReplicatedLogEntry> boolean appendReceived(final T entry, final Consumer<T> callback) {
+ public boolean appendReceived(final ReplicatedLogEntry entry, final Consumer<LogEntry> callback) {
if (callback != null) {
callback.accept(entry);
}