YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/master/master_client_service.cc
Line
Count
Source (jump to first uncovered line)
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
#include "yb/master/catalog_manager.h"
15
#include "yb/master/master_client.service.h"
16
#include "yb/master/master_service_base.h"
17
#include "yb/master/master_service_base-internal.h"
18
19
#include "yb/util/flag_tags.h"
20
21
DEFINE_int32(master_inject_latency_on_tablet_lookups_ms, 0,
22
             "Number of milliseconds that the master will sleep before responding to "
23
             "requests for tablet locations.");
24
TAG_FLAG(master_inject_latency_on_tablet_lookups_ms, unsafe);
25
TAG_FLAG(master_inject_latency_on_tablet_lookups_ms, hidden);
26
27
DEFINE_test_flag(bool, master_fail_transactional_tablet_lookups, false,
28
                 "Whether to fail all lookup requests to transactional table.");
29
30
namespace yb {
31
namespace master {
32
33
namespace {
34
35
class MasterClientServiceImpl : public MasterServiceBase, public MasterClientIf {
36
 public:
37
  explicit MasterClientServiceImpl(Master* master)
38
5.42k
      : MasterServiceBase(master), MasterClientIf(master->metric_entity()) {}
39
40
  void GetTabletLocations(const GetTabletLocationsRequestPB* req,
41
                          GetTabletLocationsResponsePB* resp,
42
9.11k
                          rpc::RpcContext rpc) override {
43
9.11k
    SCOPED_LEADER_SHARED_LOCK(l, server_->catalog_manager_impl());
44
9.11k
    if (!l.CheckIsInitializedAndIsLeaderOrRespond(resp, &rpc)) {
45
1
      return;
46
1
    }
47
48
9.11k
    if (PREDICT_FALSE(FLAGS_master_inject_latency_on_tablet_lookups_ms > 0)) {
49
0
      SleepFor(MonoDelta::FromMilliseconds(FLAGS_master_inject_latency_on_tablet_lookups_ms));
50
0
    }
51
9.11k
    if (PREDICT_FALSE(FLAGS_TEST_master_fail_transactional_tablet_lookups)) {
52
0
      auto tables = server_->catalog_manager_impl()->GetTables(GetTablesMode::kAll);
53
0
      const auto& tablet_id = req->tablet_ids(0);
54
0
      for (const auto& table : tables) {
55
0
        TabletInfos tablets = table->GetTablets();
56
0
        for (const auto& tablet : tablets) {
57
0
          if (tablet->tablet_id() == tablet_id) {
58
0
            TableType table_type;
59
0
            {
60
0
              auto lock = table->LockForRead();
61
0
              table_type = table->metadata().state().table_type();
62
0
            }
63
0
            if (table_type == TableType::TRANSACTION_STATUS_TABLE_TYPE) {
64
0
              rpc.RespondFailure(STATUS(InvalidCommand, "TEST: Artificial failure"));
65
0
              return;
66
0
            }
67
0
            break;
68
0
          }
69
0
        }
70
0
      }
71
0
    }
72
73
    // For now all the tables in the cluster share the same replication information.
74
9.11k
    int expected_live_replicas = 0;
75
9.11k
    int expected_read_replicas = 0;
76
9.11k
    server_->catalog_manager_impl()->GetExpectedNumberOfReplicas(
77
9.11k
        &expected_live_replicas, &expected_read_replicas);
78
79
9.11k
    if (req->has_table_id()) {
80
1.24k
      const auto table_info = server_->catalog_manager_impl()->GetTableInfo(req->table_id());
81
1.24k
      if (table_info) {
82
1.24k
        const auto table_lock = table_info->LockForRead();
83
1.24k
        resp->set_partition_list_version(table_lock->pb.partition_list_version());
84
1.24k
      }
85
1.24k
    }
86
87
9.11k
    IncludeInactive include_inactive(req->has_include_inactive() && req->include_inactive());
88
89
9.17k
    for (const TabletId& tablet_id : req->tablet_ids()) {
90
      // TODO: once we have catalog data. ACL checks would also go here, probably.
91
9.17k
      TabletLocationsPB* locs_pb = resp->add_tablet_locations();
92
9.17k
      locs_pb->set_expected_live_replicas(expected_live_replicas);
93
9.17k
      locs_pb->set_expected_read_replicas(expected_read_replicas);
94
9.17k
      Status s = server_->catalog_manager_impl()->GetTabletLocations(
95
9.17k
          tablet_id, locs_pb, include_inactive);
96
9.17k
      if (!s.ok()) {
97
324
        resp->mutable_tablet_locations()->RemoveLast();
98
99
324
        GetTabletLocationsResponsePB::Error* err = resp->add_errors();
100
324
        err->set_tablet_id(tablet_id);
101
324
        StatusToPB(s, err->mutable_status());
102
324
      }
103
9.17k
    }
104
105
9.11k
    rpc.RespondSuccess();
106
9.11k
  }
107
108
  void GetTableLocations(const GetTableLocationsRequestPB* req,
109
                         GetTableLocationsResponsePB* resp,
110
167k
                         rpc::RpcContext rpc) override {
111
    // We can't use the HANDLE_ON_LEADER_WITH_LOCK macro here because we have to inject latency
112
    // before acquiring the leader lock.
113
167k
    HandleOnLeader(req, resp, &rpc, [&]() -> Status {
114
167k
      if (PREDICT_FALSE(FLAGS_master_inject_latency_on_tablet_lookups_ms > 0)) {
115
0
        SleepFor(MonoDelta::FromMilliseconds(FLAGS_master_inject_latency_on_tablet_lookups_ms));
116
0
      }
117
167k
      return server_->catalog_manager_impl()->GetTableLocations(req, resp);
118
167k
    }, __FILE__, __LINE__, __func__, HoldCatalogLock::kTrue);
119
167k
  }
120
121
  MASTER_SERVICE_IMPL_ON_LEADER_WITH_LOCK(
122
    CatalogManager,
123
    (GetTransactionStatusTablets)
124
    (GetYsqlCatalogConfig)
125
    (RedisConfigSet)
126
    (RedisConfigGet)
127
    (ReservePgsqlOids)
128
  )
129
};
130
131
} // namespace
132
133
5.42k
std::unique_ptr<rpc::ServiceIf> MakeMasterClientService(Master* master) {
134
5.42k
  return std::make_unique<MasterClientServiceImpl>(master);
135
5.42k
}
136
137
} // namespace master
138
} // namespace yb