YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/master/scoped_leader_shared_lock.h
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
32
#ifndef YB_MASTER_SCOPED_LEADER_SHARED_LOCK_H
33
#define YB_MASTER_SCOPED_LEADER_SHARED_LOCK_H
34
35
#include <chrono>
36
#include <string>
37
#include <unordered_map>
38
39
#include <glog/logging.h>
40
41
#include "yb/master/master_fwd.h"
42
43
#include "yb/rpc/service_if.h"
44
45
#include "yb/util/status_fwd.h"
46
#include "yb/util/rw_mutex.h"
47
#include "yb/util/shared_lock.h"
48
49
namespace yb {
50
namespace master {
51
52
// This is how we should instantiate ScopedLeaderSharedLock. Captures context information so we can
53
// use it in logging and debugging.
54
#define SCOPED_LEADER_SHARED_LOCK(lock_name, catalog_manager) \
55
6.24M
    ::yb::master::ScopedLeaderSharedLock lock_name( \
56
6.24M
        (catalog_manager), __FILE__, __LINE__, __func__)
57
58
// Scoped "shared lock" to serialize master leader elections.
59
//
60
// While in scope, blocks the catalog manager in the event that it becomes
61
// the leader of its Raft configuration and needs to reload its persistent
62
// metadata. Once destroyed, the catalog manager is unblocked.
63
//
64
// Usage:
65
//
66
// void MasterServiceImpl::CreateTable(const CreateTableRequestPB* req,
67
//                                     CreateTableResponsePB* resp,
68
//                                     rpc::RpcContext* rpc) {
69
//   ScopedLeaderSharedLock l(server_->catalog_manager());
70
//   if (!l.CheckIsInitializedAndIsLeaderOrRespond(resp, rpc)) {
71
//     return;
72
//   }
73
//
74
//   Status s = server_->catalog_manager()->CreateTable(req, resp, rpc);
75
//   CheckRespErrorOrSetUnknown(s, resp);
76
//   rpc.RespondSuccess();
77
// }
78
//
79
class ScopedLeaderSharedLock {
80
 public:
81
  // Creates a new shared lock, acquiring the catalog manager's leader_lock_
82
  // for reading in the process. The lock is released when this object is
83
  // destroyed.
84
  //
85
  // 'catalog' must outlive this object.
86
  explicit ScopedLeaderSharedLock(
87
      CatalogManager* catalog,
88
      const char* file_name,
89
      int line_number,
90
      const char* function_name);
91
92
  explicit ScopedLeaderSharedLock(
93
      enterprise::CatalogManager* catalog,
94
      const char* file_name,
95
      int line_number,
96
      const char* function_name);
97
98
  ~ScopedLeaderSharedLock();
99
100
  void Unlock();
101
102
  // General status of the catalog manager. If not OK (e.g. the catalog
103
  // manager is still being initialized), all operations are illegal and
104
  // leader_status() should not be trusted.
105
433k
  const Status& catalog_status() const { return catalog_status_; }
106
107
  // Leadership status of the catalog manager. If not OK, the catalog
108
  // manager is not the leader, but some operations may still be legal.
109
1.12M
  const Status& leader_status() const {
110
1.12M
    DCHECK(catalog_status_.ok());
111
1.12M
    return leader_status_;
112
1.12M
  }
113
114
  // First non-OK status of the catalog manager, adhering to the checking
115
  // order specified above.
116
901k
  const Status& first_failed_status() const {
117
901k
    if (!catalog_status_.ok()) {
118
0
      return catalog_status_;
119
0
    }
120
901k
    return leader_status_;
121
901k
  }
122
123
  // Check that the catalog manager is initialized. It may or may not be the
124
  // leader of its Raft configuration.
125
  //
126
  // If not initialized, writes the corresponding error to 'resp',
127
  // responds to 'rpc', and returns false.
128
  template<typename RespClass>
129
  bool CheckIsInitializedOrRespond(RespClass* resp, rpc::RpcContext* rpc);
130
131
  // Check that the catalog manager is initialized and that it is the leader
132
  // of its Raft configuration. Initialization status takes precedence over
133
  // leadership status.
134
  //
135
  // If not initialized or if not the leader, writes the corresponding error
136
  // to 'resp', responds to 'rpc', and returns false.
137
  template<typename RespClass>
138
  bool CheckIsInitializedAndIsLeaderOrRespond(RespClass* resp, rpc::RpcContext* rpc);
139
140
  // TServer API variant of above class to set appropriate error codes.
141
  template<typename RespClass>
142
  bool CheckIsInitializedAndIsLeaderOrRespondTServer(RespClass* resp, rpc::RpcContext* rpc);
143
144
  // If set_error is false, then the error field of resp should not be set.
145
  template<typename RespClass>
146
  bool CheckIsInitializedOrRespondTServer(RespClass* resp, rpc::RpcContext* rpc,
147
                                          bool set_error = true);
148
149
 private:
150
  template<typename RespClass, typename ErrorClass>
151
  bool CheckIsInitializedAndIsLeaderOrRespondInternal(RespClass* resp, rpc::RpcContext* rpc);
152
153
  template<typename RespClass, typename ErrorClass>
154
  bool CheckIsInitializedOrRespondInternal(RespClass* resp, rpc::RpcContext* rpc,
155
                                           bool set_error = true);
156
157
  CatalogManager* catalog_;
158
  shared_lock<RWMutex> leader_shared_lock_;
159
  Status catalog_status_;
160
  Status leader_status_;
161
  std::chrono::steady_clock::time_point start_;
162
163
  const char* file_name_;
164
  int line_number_;
165
  const char* function_name_;
166
};
167
168
}  // namespace master
169
}  // namespace yb
170
171
#endif  // YB_MASTER_SCOPED_LEADER_SHARED_LOCK_H