2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.raft;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.base.Strings;
14 import com.google.common.base.Suppliers;
15 import java.util.concurrent.TimeUnit;
16 import java.util.function.Supplier;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.controller.cluster.raft.policy.DefaultRaftPolicy;
19 import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 import scala.concurrent.duration.FiniteDuration;
25 * Default implementation of the ConfigParams.
27 public class DefaultConfigParamsImpl implements ConfigParams {
29 private static final Logger LOG = LoggerFactory.getLogger(DefaultConfigParamsImpl.class);
31 private static final int SNAPSHOT_BATCH_COUNT = 20000;
33 * Interval after which a snapshot should be taken during the recovery process. 0 if never.
35 private static final int RECOVERY_SNAPSHOT_INTERVAL_SECONDS = 0;
37 private static final int JOURNAL_RECOVERY_LOG_BATCH_SIZE = 1000;
40 * The maximum election time variance.
42 private static final int ELECTION_TIME_MAX_VARIANCE = 100;
44 private static final int SNAPSHOT_CHUNK_SIZE = 2048 * 1000; //2MB
48 * The interval at which a heart beat message will be sent to the remote
52 * Since this is set to 100 milliseconds the Election timeout should be
53 * at least 200 milliseconds
55 public static final FiniteDuration HEART_BEAT_INTERVAL =
56 new FiniteDuration(100, TimeUnit.MILLISECONDS);
58 private final Supplier<RaftPolicy> policySupplier = Suppliers.memoize(this::getPolicy);
60 private FiniteDuration heartBeatInterval = HEART_BEAT_INTERVAL;
61 private long snapshotBatchCount = SNAPSHOT_BATCH_COUNT;
62 private int journalRecoveryLogBatchSize = JOURNAL_RECOVERY_LOG_BATCH_SIZE;
63 private int recoverySnapshotIntervalSeconds = RECOVERY_SNAPSHOT_INTERVAL_SECONDS;
64 private long isolatedLeaderCheckInterval = HEART_BEAT_INTERVAL.$times(1000).toMillis();
65 private FiniteDuration electionTimeOutInterval;
67 // 12 is just an arbitrary percentage. This is the amount of the total memory that a raft actor's
68 // in-memory journal can use before it needs to snapshot
69 private int snapshotDataThresholdPercentage = 12;
71 // max size of in-memory journal in MB
72 // 0 means direct threshold if disabled
73 private int snapshotDataThreshold = 0;
75 private int snapshotChunkSize = SNAPSHOT_CHUNK_SIZE;
77 private long electionTimeoutFactor = 2;
78 private long candidateElectionTimeoutDivisor = 1;
79 private String customRaftPolicyImplementationClass;
81 private PeerAddressResolver peerAddressResolver = NoopPeerAddressResolver.INSTANCE;
83 private String tempFileDirectory = "";
85 private int fileBackedStreamingThreshold = 128 * MEGABYTE;
87 private long syncIndexThreshold = 10;
89 public void setHeartBeatInterval(final FiniteDuration heartBeatInterval) {
90 this.heartBeatInterval = heartBeatInterval;
91 electionTimeOutInterval = null;
94 public void setSnapshotBatchCount(final long snapshotBatchCount) {
95 this.snapshotBatchCount = snapshotBatchCount;
98 public void setRecoverySnapshotIntervalSeconds(int recoverySnapshotInterval) {
99 checkArgument(recoverySnapshotInterval >= 0);
100 this.recoverySnapshotIntervalSeconds = recoverySnapshotInterval;
103 public void setSnapshotDataThresholdPercentage(final int snapshotDataThresholdPercentage) {
104 this.snapshotDataThresholdPercentage = snapshotDataThresholdPercentage;
107 public void setSnapshotDataThreshold(final int snapshotDataThreshold) {
108 this.snapshotDataThreshold = snapshotDataThreshold;
111 public void setSnapshotChunkSize(final int snapshotChunkSize) {
112 this.snapshotChunkSize = snapshotChunkSize;
115 public void setJournalRecoveryLogBatchSize(final int journalRecoveryLogBatchSize) {
116 this.journalRecoveryLogBatchSize = journalRecoveryLogBatchSize;
119 public void setIsolatedLeaderCheckInterval(final FiniteDuration isolatedLeaderCheckInterval) {
120 this.isolatedLeaderCheckInterval = isolatedLeaderCheckInterval.toMillis();
123 public void setElectionTimeoutFactor(final long electionTimeoutFactor) {
124 this.electionTimeoutFactor = electionTimeoutFactor;
125 electionTimeOutInterval = null;
128 public void setCandidateElectionTimeoutDivisor(final long candidateElectionTimeoutDivisor) {
129 this.candidateElectionTimeoutDivisor = candidateElectionTimeoutDivisor;
132 public void setTempFileDirectory(final String tempFileDirectory) {
133 this.tempFileDirectory = tempFileDirectory;
136 public void setFileBackedStreamingThreshold(final int fileBackedStreamingThreshold) {
137 this.fileBackedStreamingThreshold = fileBackedStreamingThreshold;
140 public void setCustomRaftPolicyImplementationClass(final String customRaftPolicyImplementationClass) {
141 this.customRaftPolicyImplementationClass = customRaftPolicyImplementationClass;
145 public String getCustomRaftPolicyImplementationClass() {
146 return customRaftPolicyImplementationClass;
150 public long getSnapshotBatchCount() {
151 return snapshotBatchCount;
155 public int getSnapshotDataThresholdPercentage() {
156 return snapshotDataThresholdPercentage;
160 public int getSnapshotDataThreshold() {
161 return snapshotDataThreshold;
165 public int getRecoverySnapshotIntervalSeconds() {
166 return this.recoverySnapshotIntervalSeconds;
170 public FiniteDuration getHeartBeatInterval() {
171 return heartBeatInterval;
175 public FiniteDuration getElectionTimeOutInterval() {
176 if (electionTimeOutInterval == null) {
177 electionTimeOutInterval = getHeartBeatInterval().$times(electionTimeoutFactor);
180 return electionTimeOutInterval;
184 public long getCandidateElectionTimeoutDivisor() {
185 return candidateElectionTimeoutDivisor;
189 public int getElectionTimeVariance() {
190 return ELECTION_TIME_MAX_VARIANCE;
194 public int getSnapshotChunkSize() {
195 return snapshotChunkSize;
199 public int getJournalRecoveryLogBatchSize() {
200 return journalRecoveryLogBatchSize;
204 public long getIsolatedCheckIntervalInMillis() {
205 return isolatedLeaderCheckInterval;
209 public long getElectionTimeoutFactor() {
210 return electionTimeoutFactor;
214 public RaftPolicy getRaftPolicy() {
215 return policySupplier.get();
219 public String getTempFileDirectory() {
220 return tempFileDirectory;
224 public int getFileBackedStreamingThreshold() {
225 return fileBackedStreamingThreshold;
230 public PeerAddressResolver getPeerAddressResolver() {
231 return peerAddressResolver;
234 public void setPeerAddressResolver(final @NonNull PeerAddressResolver peerAddressResolver) {
235 this.peerAddressResolver = requireNonNull(peerAddressResolver);
239 public long getSyncIndexThreshold() {
240 return syncIndexThreshold;
243 public void setSyncIndexThreshold(final long syncIndexThreshold) {
244 checkArgument(syncIndexThreshold >= 0);
245 this.syncIndexThreshold = syncIndexThreshold;
248 @SuppressWarnings("checkstyle:IllegalCatch")
249 private RaftPolicy getPolicy() {
250 if (Strings.isNullOrEmpty(DefaultConfigParamsImpl.this.customRaftPolicyImplementationClass)) {
251 LOG.debug("No custom RaftPolicy specified. Using DefaultRaftPolicy");
252 return DefaultRaftPolicy.INSTANCE;
256 String className = DefaultConfigParamsImpl.this.customRaftPolicyImplementationClass;
257 LOG.info("Trying to use custom RaftPolicy {}", className);
258 return (RaftPolicy)Class.forName(className).getDeclaredConstructor().newInstance();
259 } catch (ClassCastException | ReflectiveOperationException e) {
260 if (LOG.isDebugEnabled()) {
261 LOG.error("Could not create custom raft policy, will stick with default", e);
263 LOG.error("Could not create custom raft policy, will stick with default : cause = {}",
267 return DefaultRaftPolicy.INSTANCE;