/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 | 8.03k | : MasterServiceBase(master), MasterClientIf(master->metric_entity()) {} |
39 | | |
40 | | void GetTabletLocations(const GetTabletLocationsRequestPB* req, |
41 | | GetTabletLocationsResponsePB* resp, |
42 | 15.2k | rpc::RpcContext rpc) override { |
43 | 15.2k | SCOPED_LEADER_SHARED_LOCK(l, server_->catalog_manager_impl()); |
44 | 15.2k | if (!l.CheckIsInitializedAndIsLeaderOrRespond(resp, &rpc)) { |
45 | 30 | return; |
46 | 30 | } |
47 | | |
48 | 15.2k | 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 | 15.2k | 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 | 15.2k | int expected_live_replicas = 0; |
75 | 15.2k | int expected_read_replicas = 0; |
76 | 15.2k | server_->catalog_manager_impl()->GetExpectedNumberOfReplicas( |
77 | 15.2k | &expected_live_replicas, &expected_read_replicas); |
78 | | |
79 | 15.2k | if (req->has_table_id()) { |
80 | 2.08k | const auto table_info = server_->catalog_manager_impl()->GetTableInfo(req->table_id()); |
81 | 2.08k | if (table_info) { |
82 | 2.08k | const auto table_lock = table_info->LockForRead(); |
83 | 2.08k | resp->set_partition_list_version(table_lock->pb.partition_list_version()); |
84 | 2.08k | } |
85 | 2.08k | } |
86 | | |
87 | 15.2k | IncludeInactive include_inactive(req->has_include_inactive() && req->include_inactive()15.0k ); |
88 | | |
89 | 15.7k | for (const TabletId& tablet_id : req->tablet_ids()) { |
90 | | // TODO: once we have catalog data. ACL checks would also go here, probably. |
91 | 15.7k | TabletLocationsPB* locs_pb = resp->add_tablet_locations(); |
92 | 15.7k | locs_pb->set_expected_live_replicas(expected_live_replicas); |
93 | 15.7k | locs_pb->set_expected_read_replicas(expected_read_replicas); |
94 | 15.7k | Status s = server_->catalog_manager_impl()->GetTabletLocations( |
95 | 15.7k | tablet_id, locs_pb, include_inactive); |
96 | 15.7k | if (!s.ok()) { |
97 | 360 | resp->mutable_tablet_locations()->RemoveLast(); |
98 | | |
99 | 360 | GetTabletLocationsResponsePB::Error* err = resp->add_errors(); |
100 | 360 | err->set_tablet_id(tablet_id); |
101 | 360 | StatusToPB(s, err->mutable_status()); |
102 | 360 | } |
103 | 15.7k | } |
104 | | |
105 | 15.2k | rpc.RespondSuccess(); |
106 | 15.2k | } |
107 | | |
108 | | void GetTableLocations(const GetTableLocationsRequestPB* req, |
109 | | GetTableLocationsResponsePB* resp, |
110 | 228k | 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 | 228k | HandleOnLeader(req, resp, &rpc, [&]() -> Status { |
114 | 228k | 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 | 228k | return server_->catalog_manager_impl()->GetTableLocations(req, resp); |
118 | 228k | }, __FILE__, __LINE__, __func__, HoldCatalogLock::kTrue); |
119 | 228k | } |
120 | | |
121 | | MASTER_SERVICE_IMPL_ON_LEADER_WITH_LOCK( |
122 | | CatalogManager, |
123 | | (GetYsqlCatalogConfig) |
124 | | (RedisConfigSet) |
125 | | (RedisConfigGet) |
126 | | (ReservePgsqlOids) |
127 | | ) |
128 | | |
129 | | MASTER_SERVICE_IMPL_ON_LEADER_WITHOUT_LOCK( |
130 | | CatalogManager, |
131 | | (GetTransactionStatusTablets) |
132 | | ) |
133 | | }; |
134 | | |
135 | | } // namespace |
136 | | |
137 | 8.03k | std::unique_ptr<rpc::ServiceIf> MakeMasterClientService(Master* master) { |
138 | 8.03k | return std::make_unique<MasterClientServiceImpl>(master); |
139 | 8.03k | } |
140 | | |
141 | | } // namespace master |
142 | | } // namespace yb |