64502858a754b294c8f3b2d2aca31e056639f9f4
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / main / java / org / opendaylight / controller / cluster / raft / DefaultConfigParamsImpl.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.cluster.raft;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.base.Strings;
12 import com.google.common.base.Supplier;
13 import com.google.common.base.Suppliers;
14 import java.util.concurrent.TimeUnit;
15 import javax.annotation.Nonnull;
16 import org.opendaylight.controller.cluster.raft.policy.DefaultRaftPolicy;
17 import org.opendaylight.controller.cluster.raft.policy.RaftPolicy;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20 import scala.concurrent.duration.FiniteDuration;
21
22 /**
23  * Default implementation of the ConfigParams.
24  */
25 public class DefaultConfigParamsImpl implements ConfigParams {
26
27     private static final Logger LOG = LoggerFactory.getLogger(DefaultConfigParamsImpl.class);
28
29     private static final int SNAPSHOT_BATCH_COUNT = 20000;
30
31     private static final int JOURNAL_RECOVERY_LOG_BATCH_SIZE = 1000;
32
33     /**
34      * The maximum election time variance.
35      */
36     private static final int ELECTION_TIME_MAX_VARIANCE = 100;
37
38     private static final int SNAPSHOT_CHUNK_SIZE = 2048 * 1000; //2MB
39
40
41     /**
42      * The interval at which a heart beat message will be sent to the remote
43      * RaftActor.
44      *
45      * <p>
46      * Since this is set to 100 milliseconds the Election timeout should be
47      * at least 200 milliseconds
48      */
49     public static final FiniteDuration HEART_BEAT_INTERVAL =
50         new FiniteDuration(100, TimeUnit.MILLISECONDS);
51
52     private final Supplier<RaftPolicy> policySupplier = Suppliers.memoize(this::getPolicy);
53
54     private FiniteDuration heartBeatInterval = HEART_BEAT_INTERVAL;
55     private long snapshotBatchCount = SNAPSHOT_BATCH_COUNT;
56     private int journalRecoveryLogBatchSize = JOURNAL_RECOVERY_LOG_BATCH_SIZE;
57     private long isolatedLeaderCheckInterval = HEART_BEAT_INTERVAL.$times(1000).toMillis();
58     private FiniteDuration electionTimeOutInterval;
59
60     // 12 is just an arbitrary percentage. This is the amount of the total memory that a raft actor's
61     // in-memory journal can use before it needs to snapshot
62     private int snapshotDataThresholdPercentage = 12;
63
64     private int snapshotChunkSize = SNAPSHOT_CHUNK_SIZE;
65
66     private long electionTimeoutFactor = 2;
67     private String customRaftPolicyImplementationClass;
68
69     private PeerAddressResolver peerAddressResolver = NoopPeerAddressResolver.INSTANCE;
70
71     private String tempFileDirectory = "";
72
73     private int fileBackedStreamingThreshold = 128 * MEGABYTE;
74
75     private long syncIndexThreshold = 10;
76
77     public void setHeartBeatInterval(final FiniteDuration heartBeatInterval) {
78         this.heartBeatInterval = heartBeatInterval;
79         electionTimeOutInterval = null;
80     }
81
82     public void setSnapshotBatchCount(final long snapshotBatchCount) {
83         this.snapshotBatchCount = snapshotBatchCount;
84     }
85
86     public void setSnapshotDataThresholdPercentage(final int snapshotDataThresholdPercentage) {
87         this.snapshotDataThresholdPercentage = snapshotDataThresholdPercentage;
88     }
89
90     public void setSnapshotChunkSize(final int snapshotChunkSize) {
91         this.snapshotChunkSize = snapshotChunkSize;
92     }
93
94     public void setJournalRecoveryLogBatchSize(final int journalRecoveryLogBatchSize) {
95         this.journalRecoveryLogBatchSize = journalRecoveryLogBatchSize;
96     }
97
98     public void setIsolatedLeaderCheckInterval(final FiniteDuration isolatedLeaderCheckInterval) {
99         this.isolatedLeaderCheckInterval = isolatedLeaderCheckInterval.toMillis();
100     }
101
102     public void setElectionTimeoutFactor(final long electionTimeoutFactor) {
103         this.electionTimeoutFactor = electionTimeoutFactor;
104         electionTimeOutInterval = null;
105     }
106
107     public void setTempFileDirectory(final String tempFileDirectory) {
108         this.tempFileDirectory = tempFileDirectory;
109     }
110
111     public void setFileBackedStreamingThreshold(final int fileBackedStreamingThreshold) {
112         this.fileBackedStreamingThreshold = fileBackedStreamingThreshold;
113     }
114
115     public void setCustomRaftPolicyImplementationClass(final String customRaftPolicyImplementationClass) {
116         this.customRaftPolicyImplementationClass = customRaftPolicyImplementationClass;
117     }
118
119     @Override
120     public String getCustomRaftPolicyImplementationClass() {
121         return customRaftPolicyImplementationClass;
122     }
123
124     @Override
125     public long getSnapshotBatchCount() {
126         return snapshotBatchCount;
127     }
128
129     @Override
130     public int getSnapshotDataThresholdPercentage() {
131         return snapshotDataThresholdPercentage;
132     }
133
134
135     @Override
136     public FiniteDuration getHeartBeatInterval() {
137         return heartBeatInterval;
138     }
139
140     @Override
141     public FiniteDuration getElectionTimeOutInterval() {
142         if (electionTimeOutInterval == null) {
143             electionTimeOutInterval = getHeartBeatInterval().$times(electionTimeoutFactor);
144         }
145
146         return electionTimeOutInterval;
147     }
148
149     @Override
150     public int getElectionTimeVariance() {
151         return ELECTION_TIME_MAX_VARIANCE;
152     }
153
154     @Override
155     public int getSnapshotChunkSize() {
156         return snapshotChunkSize;
157     }
158
159     @Override
160     public int getJournalRecoveryLogBatchSize() {
161         return journalRecoveryLogBatchSize;
162     }
163
164     @Override
165     public long getIsolatedCheckIntervalInMillis() {
166         return isolatedLeaderCheckInterval;
167     }
168
169     @Override
170     public long getElectionTimeoutFactor() {
171         return electionTimeoutFactor;
172     }
173
174     @Override
175     public RaftPolicy getRaftPolicy() {
176         return policySupplier.get();
177     }
178
179     @Override
180     public String getTempFileDirectory() {
181         return tempFileDirectory;
182     }
183
184     @Override
185     public int getFileBackedStreamingThreshold() {
186         return fileBackedStreamingThreshold;
187     }
188
189
190     @Override
191     public PeerAddressResolver getPeerAddressResolver() {
192         return peerAddressResolver;
193     }
194
195     public void setPeerAddressResolver(@Nonnull final PeerAddressResolver peerAddressResolver) {
196         this.peerAddressResolver = Preconditions.checkNotNull(peerAddressResolver);
197     }
198
199     @Override
200     public long getSyncIndexThreshold() {
201         return syncIndexThreshold;
202     }
203
204     public void setSyncIndexThreshold(final long syncIndexThreshold) {
205         Preconditions.checkArgument(syncIndexThreshold >= 0);
206         this.syncIndexThreshold = syncIndexThreshold;
207     }
208
209     @SuppressWarnings("checkstyle:IllegalCatch")
210     private RaftPolicy getPolicy() {
211         if (Strings.isNullOrEmpty(DefaultConfigParamsImpl.this.customRaftPolicyImplementationClass)) {
212             LOG.debug("No custom RaftPolicy specified. Using DefaultRaftPolicy");
213             return DefaultRaftPolicy.INSTANCE;
214         }
215
216         try {
217             String className = DefaultConfigParamsImpl.this.customRaftPolicyImplementationClass;
218             LOG.info("Trying to use custom RaftPolicy {}", className);
219             return (RaftPolicy)Class.forName(className).newInstance();
220         } catch (Exception e) {
221             if (LOG.isDebugEnabled()) {
222                 LOG.error("Could not create custom raft policy, will stick with default", e);
223             } else {
224                 LOG.error("Could not create custom raft policy, will stick with default : cause = {}",
225                     e.getMessage());
226             }
227         }
228         return DefaultRaftPolicy.INSTANCE;
229     }
230 }