YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/consensus/consensus_round.h
Line
Count
Source
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
14
#ifndef YB_CONSENSUS_CONSENSUS_ROUND_H
15
#define YB_CONSENSUS_CONSENSUS_ROUND_H
16
17
#include <stdint.h>
18
19
#include <cstdint>
20
21
#include "yb/consensus/consensus_fwd.h"
22
23
#include "yb/gutil/ref_counted.h"
24
25
#include "yb/util/opid.h"
26
27
namespace yb {
28
namespace consensus {
29
30
class ConsensusRoundCallback {
31
 public:
32
  // Invoked when appropriate operation was appended to leader consensus queue.
33
  // op_id - assigned operation id.
34
  // committed_op_id - committed operation id.
35
  //
36
  // Should initialize appropriate replicate message.
37
  virtual void AddedToLeader(const OpId& op_id, const OpId& committed_op_id) = 0;
38
39
  // Invoked when appropriate operation replication finished.
40
  virtual void ReplicationFinished(
41
      const Status& status, int64_t leader_term, OpIds* applied_op_ids) = 0;
42
43
  // Utility method for failed replication.
44
17
  void ReplicationFailed(const Status& status) {
45
17
    ReplicationFinished(status, OpId::kUnknownTerm, /* applied_op_ids= */ nullptr);
46
17
  }
47
48
13.6M
  virtual ~ConsensusRoundCallback() = default;
49
};
50
51
class ConsensusRound : public RefCountedThreadSafe<ConsensusRound> {
52
 public:
53
  // consensus lifetime should be greater than lifetime of its rounds.
54
  ConsensusRound(Consensus* consensus, ReplicateMsgPtr replicate_msg);
55
56
113k
  Consensus* consensus() const {
57
113k
    return consensus_;
58
113k
  }
59
60
2.51M
  int64_t bound_term() const {
61
2.51M
    return bound_term_;
62
2.51M
  }
63
64
74.1M
  const ReplicateMsgPtr& replicate_msg() const {
65
74.1M
    return replicate_msg_;
66
74.1M
  }
67
68
  // Returns the id of the (replicate) operation this context
69
  // refers to. This is only set _after_ Consensus::Replicate(context).
70
  OpId id() const;
71
72
  // Caller should guarantee that callback is alive until replication finishes.
73
7.79M
  void SetCallback(ConsensusRoundCallback* callback) {
74
7.79M
    callback_ = callback;
75
7.79M
  }
76
77
113k
  void SetCallback(std::unique_ptr<ConsensusRoundCallback> callback) {
78
113k
    callback_holder_ = std::move(callback);
79
113k
    callback_ = callback_holder_.get();
80
113k
  }
81
82
2.73M
  ConsensusRoundCallback* callback() const {
83
2.73M
    return callback_;
84
2.73M
  }
85
86
  // If a continuation was set, notifies it that the round has been replicated.
87
  void NotifyReplicationFinished(
88
      const Status& status, int64_t leader_term, OpIds* applied_op_ids);
89
90
  // Binds this round such that it may not be eventually executed in any term
91
  // other than 'term'.
92
  // See CheckBoundTerm().
93
2.69M
  void BindToTerm(int64_t term) {
94
2.69M
    bound_term_ = term;
95
2.69M
  }
96
97
  // Check for a rare race in which an operation is submitted to the LEADER in some term,
98
  // then before the operation is prepared, the replica loses its leadership, receives
99
  // more operations as a FOLLOWER, and then regains its leadership. We detect this case
100
  // by setting the ConsensusRound's "bound term" when it is first submitted to the
101
  // PREPARE queue, and validate that the term is still the same when we have finished
102
  // preparing it. See KUDU-597 for details.
103
  //
104
  // If this round has not been bound to any term, this is a no-op.
105
  CHECKED_STATUS CheckBoundTerm(int64_t current_term) const;
106
107
  std::string ToString() const;
108
109
 private:
110
  friend class RaftConsensusQuorumTest;
111
  friend class RefCountedThreadSafe<ConsensusRound>;
112
113
7.90M
  ~ConsensusRound() {}
114
115
  Consensus* const consensus_;
116
  // This round's replicate message.
117
  ReplicateMsgPtr replicate_msg_;
118
119
  // The leader term that this round was submitted in. CheckBoundTerm()
120
  // ensures that, when it is eventually replicated, the term has not
121
  // changed in the meantime.
122
  //
123
  // Set to -1 if no term has been bound.
124
  int64_t bound_term_ = OpId::kUnknownTerm;
125
126
  ConsensusRoundCallback* callback_ = nullptr;
127
  std::unique_ptr<ConsensusRoundCallback> callback_holder_;
128
};
129
130
}  // namespace consensus
131
}  // namespace yb
132
133
#endif  // YB_CONSENSUS_CONSENSUS_ROUND_H