/Users/deen/code/yugabyte-db/src/yb/master/async_rpc_tasks.h
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 | | #ifndef YB_MASTER_ASYNC_RPC_TASKS_H |
14 | | #define YB_MASTER_ASYNC_RPC_TASKS_H |
15 | | |
16 | | #include <atomic> |
17 | | #include <string> |
18 | | |
19 | | #include <boost/optional/optional.hpp> |
20 | | |
21 | | #include "yb/common/constants.h" |
22 | | #include "yb/common/entity_ids.h" |
23 | | #include "yb/common/snapshot.h" |
24 | | #include "yb/common/transaction.h" |
25 | | |
26 | | #include "yb/consensus/consensus.pb.h" |
27 | | #include "yb/consensus/metadata.pb.h" |
28 | | |
29 | | #include "yb/gutil/ref_counted.h" |
30 | | #include "yb/gutil/strings/substitute.h" |
31 | | |
32 | | #include "yb/master/master_fwd.h" |
33 | | |
34 | | #include "yb/rpc/rpc_controller.h" |
35 | | |
36 | | #include "yb/server/monitored_task.h" |
37 | | |
38 | | #include "yb/tserver/tserver_fwd.h" |
39 | | #include "yb/tserver/tserver_admin.pb.h" |
40 | | #include "yb/tserver/tserver_service.pb.h" |
41 | | |
42 | | #include "yb/util/status_fwd.h" |
43 | | #include "yb/util/memory/memory.h" |
44 | | #include "yb/util/metrics_fwd.h" |
45 | | |
46 | | namespace yb { |
47 | | |
48 | | struct TransactionMetadata; |
49 | | class ThreadPool; |
50 | | |
51 | | namespace consensus { |
52 | | class ConsensusServiceProxy; |
53 | | } |
54 | | |
55 | | namespace tserver { |
56 | | class TabletServerAdminServiceProxy; |
57 | | class TabletServerServiceProxy; |
58 | | } |
59 | | |
60 | | namespace master { |
61 | | |
62 | | class TSDescriptor; |
63 | | class Master; |
64 | | |
65 | | class TableInfo; |
66 | | class TabletInfo; |
67 | | |
68 | | // Interface used by RetryingTSRpcTask to pick the tablet server to |
69 | | // send the next RPC to. |
70 | | class TSPicker { |
71 | | public: |
72 | 421k | TSPicker() {} |
73 | 281k | virtual ~TSPicker() {} |
74 | | |
75 | | // Sets *ts_desc to the tablet server to contact for the next RPC. |
76 | | // |
77 | | // This assumes that TSDescriptors are never deleted by the master, |
78 | | // so the caller does not take ownership of the returned pointer. |
79 | | virtual Status PickReplica(TSDescriptor** ts_desc) = 0; |
80 | | |
81 | | private: |
82 | | DISALLOW_COPY_AND_ASSIGN(TSPicker); |
83 | | }; |
84 | | |
85 | | // Implementation of TSPicker which sends to a specific tablet server, |
86 | | // identified by its UUID. |
87 | | class PickSpecificUUID : public TSPicker { |
88 | | public: |
89 | | PickSpecificUUID(Master* master, std::string ts_uuid) |
90 | 264k | : master_(master), ts_uuid_(std::move(ts_uuid)) {} |
91 | | |
92 | | Status PickReplica(TSDescriptor** ts_desc) override; |
93 | | |
94 | | private: |
95 | | Master* const master_; |
96 | | const std::string ts_uuid_; |
97 | | |
98 | | DISALLOW_COPY_AND_ASSIGN(PickSpecificUUID); |
99 | | }; |
100 | | |
101 | | // Implementation of TSPicker which locates the current leader replica, |
102 | | // and sends the RPC to that server. |
103 | | class PickLeaderReplica : public TSPicker { |
104 | | public: |
105 | | explicit PickLeaderReplica(const scoped_refptr<TabletInfo>& tablet); |
106 | | |
107 | | Status PickReplica(TSDescriptor** ts_desc) override; |
108 | | |
109 | | private: |
110 | | const scoped_refptr<TabletInfo> tablet_; |
111 | | }; |
112 | | |
113 | | // A background task which continuously retries sending an RPC to a tablet server. |
114 | | // |
115 | | // The target tablet server is refreshed before each RPC by consulting the provided |
116 | | // TSPicker implementation. |
117 | | class RetryingTSRpcTask : public server::MonitoredTask { |
118 | | public: |
119 | | RetryingTSRpcTask(Master *master, |
120 | | ThreadPool* callback_pool, |
121 | | std::unique_ptr<TSPicker> replica_picker, |
122 | | const scoped_refptr<TableInfo>& table); |
123 | | |
124 | | ~RetryingTSRpcTask(); |
125 | | |
126 | | // Send the subclass RPC request. |
127 | | CHECKED_STATUS Run(); |
128 | | |
129 | | // Abort this task and return its value before it was successfully aborted. If the task entered |
130 | | // a different terminal state before we were able to abort it, return that state. |
131 | | server::MonitoredTaskState AbortAndReturnPrevState(const Status& status) override; |
132 | | |
133 | 2.44M | server::MonitoredTaskState state() const override { |
134 | 2.44M | return state_.load(std::memory_order_acquire); |
135 | 2.44M | } |
136 | | |
137 | 185k | MonoTime start_timestamp() const override { return start_ts_; } |
138 | 0 | MonoTime completion_timestamp() const override { return end_ts_; } |
139 | 112k | const scoped_refptr<TableInfo>& table() const { return table_ ; } |
140 | | |
141 | | protected: |
142 | | // Send an RPC request and register a callback. |
143 | | // The implementation must return true if the callback was registered, and |
144 | | // false if an error occurred and no callback will occur. |
145 | | virtual bool SendRequest(int attempt) = 0; |
146 | | |
147 | | // Handle the response from the RPC request. On success, MarkSuccess() must |
148 | | // be called to mutate the state_ variable. If retry is desired, then |
149 | | // no state change is made. Retries will automatically be attempted as long |
150 | | // as the state is MonitoredTaskState::kRunning and deadline_ has not yet passed. |
151 | | virtual void HandleResponse(int attempt) = 0; |
152 | | |
153 | | // Return the id of the tablet that is the subject of the async request. |
154 | | virtual TabletId tablet_id() const = 0; |
155 | | |
156 | | virtual Status ResetTSProxy(); |
157 | | |
158 | | // Overridable log prefix with reasonable default. |
159 | | std::string LogPrefix() const; |
160 | | |
161 | | bool PerformStateTransition( |
162 | | server::MonitoredTaskState expected, server::MonitoredTaskState new_state) |
163 | 974k | WARN_UNUSED_RESULT { |
164 | 974k | return state_.compare_exchange_strong(expected, new_state); |
165 | 974k | } |
166 | | |
167 | | void TransitionToTerminalState( |
168 | | server::MonitoredTaskState expected, server::MonitoredTaskState terminal_state, |
169 | | const Status& status); |
170 | | bool TransitionToWaitingState(server::MonitoredTaskState expected); |
171 | | |
172 | | // Transition this task state from running to complete. |
173 | | void TransitionToCompleteState(); |
174 | | |
175 | | // Transition this task state from expected to failed with specified status. |
176 | | void TransitionToFailedState(server::MonitoredTaskState expected, const Status& status); |
177 | | |
178 | 420k | virtual void Finished(const Status& status) {} |
179 | | |
180 | | void AbortTask(const Status& status); |
181 | | |
182 | | virtual MonoTime ComputeDeadline(); |
183 | | // Callback meant to be invoked from asynchronous RPC service proxy calls. |
184 | | void RpcCallback(); |
185 | | |
186 | 462k | auto BindRpcCallback() { |
187 | 462k | return std::bind(&RetryingTSRpcTask::RpcCallback, shared_from(this)); |
188 | 462k | } |
189 | | |
190 | | // Handle the actual work of the RPC callback. This is run on the master's worker |
191 | | // pool, rather than a reactor thread, so it may do blocking IO operations. |
192 | | void DoRpcCallback(); |
193 | | |
194 | | // Called when the async task unregisters either successfully or unsuccessfully. |
195 | | // |
196 | | // Note: This is the last thing function called, to guarantee it's the last work done by the task. |
197 | | virtual void UnregisterAsyncTaskCallback(); |
198 | | |
199 | | string table_name() const; |
200 | | |
201 | | Master* const master_; |
202 | | ThreadPool* const callback_pool_; |
203 | | const std::unique_ptr<TSPicker> replica_picker_; |
204 | | const scoped_refptr<TableInfo> table_; |
205 | | |
206 | | void UpdateMetrics(scoped_refptr<Histogram> metric, MonoTime start_time, |
207 | | const string& metric_name, |
208 | | const string& metric_type); |
209 | | |
210 | | MonoTime start_ts_; |
211 | | MonoTime attempt_start_ts_; |
212 | | MonoTime end_ts_; |
213 | | MonoTime deadline_; |
214 | | |
215 | | int attempt_ = 0; |
216 | | rpc::RpcController rpc_; |
217 | | TSDescriptor* target_ts_desc_ = nullptr; |
218 | | std::shared_ptr<tserver::TabletServerServiceProxy> ts_proxy_; |
219 | | std::shared_ptr<tserver::TabletServerAdminServiceProxy> ts_admin_proxy_; |
220 | | std::shared_ptr<tserver::TabletServerBackupServiceProxy> ts_backup_proxy_; |
221 | | std::shared_ptr<consensus::ConsensusServiceProxy> consensus_proxy_; |
222 | | |
223 | | std::atomic<rpc::ScheduledTaskId> reactor_task_id_{rpc::kInvalidTaskId}; |
224 | | |
225 | | // Mutex protecting calls to UnregisterAsyncTask to avoid races between Run and user triggered |
226 | | // Aborts. |
227 | | std::mutex unregister_mutex_; |
228 | | |
229 | | private: |
230 | | // Returns true if we should impose a limit in the number of retries for this task type. |
231 | 45.4k | bool RetryLimitTaskType() { |
232 | 45.4k | return type() != ASYNC_CREATE_REPLICA && type() != ASYNC_DELETE_REPLICA44.9k ; |
233 | 45.4k | } |
234 | | |
235 | | // Returns true if we should not retry for this task type. |
236 | 45.4k | bool NoRetryTaskType() { |
237 | 45.4k | return type() == ASYNC_FLUSH_TABLETS; |
238 | 45.4k | } |
239 | | |
240 | | // Reschedules the current task after a backoff delay. |
241 | | // Returns false if the task was not rescheduled due to reaching the maximum |
242 | | // timeout or because the task is no longer in a running state. |
243 | | // Returns true if rescheduling the task was successful. |
244 | | bool RescheduleWithBackoffDelay(); |
245 | | |
246 | | // Callback for Reactor delayed task mechanism. Called either when it is time |
247 | | // to execute the delayed task (with status == OK) or when the task |
248 | | // is cancelled, i.e. when the scheduling timer is shut down (status != OK). |
249 | | void RunDelayedTask(const Status& status); |
250 | | |
251 | | // Clean up request and release resources. May call 'delete this'. |
252 | | void UnregisterAsyncTask(); |
253 | | |
254 | | CHECKED_STATUS Failed(const Status& status); |
255 | | |
256 | | // Only abort this task on reactor if it has been scheduled. |
257 | | void AbortIfScheduled(); |
258 | | |
259 | | virtual int num_max_retries(); |
260 | | virtual int max_delay_ms(); |
261 | | |
262 | | // Use state() and MarkX() accessors. |
263 | | std::atomic<server::MonitoredTaskState> state_{server::MonitoredTaskState::kWaiting}; |
264 | | }; |
265 | | |
266 | | // RetryingTSRpcTask subclass which always retries the same tablet server, |
267 | | // identified by its UUID. |
268 | | class RetrySpecificTSRpcTask : public RetryingTSRpcTask { |
269 | | public: |
270 | | RetrySpecificTSRpcTask(Master* master, |
271 | | ThreadPool* callback_pool, |
272 | | const std::string& permanent_uuid, |
273 | | const scoped_refptr<TableInfo>& table) |
274 | | : RetryingTSRpcTask(master, |
275 | | callback_pool, |
276 | | std::unique_ptr<TSPicker>(new PickSpecificUUID(master, permanent_uuid)), |
277 | | table), |
278 | 264k | permanent_uuid_(permanent_uuid) { |
279 | 264k | } |
280 | | |
281 | | protected: |
282 | | const std::string permanent_uuid_; |
283 | | }; |
284 | | |
285 | | // RetryingTSRpcTask subclass which retries sending an RPC to a tablet leader. |
286 | | class AsyncTabletLeaderTask : public RetryingTSRpcTask { |
287 | | public: |
288 | | AsyncTabletLeaderTask( |
289 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet); |
290 | | |
291 | | AsyncTabletLeaderTask( |
292 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet, |
293 | | const scoped_refptr<TableInfo>& table); |
294 | | |
295 | | ~AsyncTabletLeaderTask(); |
296 | | |
297 | | std::string description() const override; |
298 | | |
299 | | TabletId tablet_id() const override; |
300 | | |
301 | | protected: |
302 | | TabletServerId permanent_uuid() const; |
303 | | |
304 | | scoped_refptr<TabletInfo> tablet_; |
305 | | }; |
306 | | |
307 | | // Fire off the async create tablet. |
308 | | // This requires that the new tablet info is locked for write, and the |
309 | | // consensus configuration information has been filled into the 'dirty' data. |
310 | | class AsyncCreateReplica : public RetrySpecificTSRpcTask { |
311 | | public: |
312 | | AsyncCreateReplica(Master *master, |
313 | | ThreadPool *callback_pool, |
314 | | const std::string& permanent_uuid, |
315 | | const scoped_refptr<TabletInfo>& tablet, |
316 | | const std::vector<SnapshotScheduleId>& snapshot_schedules); |
317 | | |
318 | 127k | Type type() const override { return ASYNC_CREATE_REPLICA; } |
319 | | |
320 | 560k | std::string type_name() const override { return "Create Tablet"; } |
321 | | |
322 | | std::string description() const override; |
323 | | |
324 | | protected: |
325 | 505 | TabletId tablet_id() const override { return tablet_id_; } |
326 | | |
327 | | void HandleResponse(int attempt) override; |
328 | | bool SendRequest(int attempt) override; |
329 | | |
330 | | private: |
331 | | const TabletId tablet_id_; |
332 | | tserver::CreateTabletRequestPB req_; |
333 | | tserver::CreateTabletResponsePB resp_; |
334 | | }; |
335 | | |
336 | | // Task to start election at hinted leader for a newly created tablet. |
337 | | class AsyncStartElection : public RetrySpecificTSRpcTask { |
338 | | public: |
339 | | AsyncStartElection(Master *master, |
340 | | ThreadPool *callback_pool, |
341 | | const std::string& permanent_uuid, |
342 | | const scoped_refptr<TabletInfo>& tablet); |
343 | | |
344 | 116k | Type type() const override { return START_ELECTION; } |
345 | | |
346 | 268k | std::string type_name() const override { return "Hinted Leader Start Election"; } |
347 | | |
348 | | std::string description() const override; |
349 | | |
350 | | protected: |
351 | 29 | TabletId tablet_id() const override { return tablet_id_; } |
352 | | |
353 | | void HandleResponse(int attempt) override; |
354 | | bool SendRequest(int attempt) override; |
355 | | |
356 | | private: |
357 | | const TabletId tablet_id_; |
358 | | consensus::RunLeaderElectionRequestPB req_; |
359 | | consensus::RunLeaderElectionResponsePB resp_; |
360 | | }; |
361 | | |
362 | | // Send a DeleteTablet() RPC request. |
363 | | class AsyncDeleteReplica : public RetrySpecificTSRpcTask { |
364 | | public: |
365 | | AsyncDeleteReplica( |
366 | | Master* master, ThreadPool* callback_pool, const std::string& permanent_uuid, |
367 | | const scoped_refptr<TableInfo>& table, TabletId tablet_id, |
368 | | tablet::TabletDataState delete_type, |
369 | | boost::optional<int64_t> cas_config_opid_index_less_or_equal, |
370 | | std::string reason) |
371 | | : RetrySpecificTSRpcTask(master, callback_pool, permanent_uuid, table), |
372 | | tablet_id_(std::move(tablet_id)), |
373 | | delete_type_(delete_type), |
374 | | cas_config_opid_index_less_or_equal_( |
375 | | std::move(cas_config_opid_index_less_or_equal)), |
376 | 75.9k | reason_(std::move(reason)) {} |
377 | | |
378 | 206k | Type type() const override { return ASYNC_DELETE_REPLICA; } |
379 | | |
380 | 308k | std::string type_name() const override { return "Delete Tablet"; } |
381 | | |
382 | | std::string description() const override; |
383 | | |
384 | 36 | void set_hide_only(bool value) { |
385 | 36 | hide_only_ = value; |
386 | 36 | } |
387 | | |
388 | | protected: |
389 | 984 | TabletId tablet_id() const override { return tablet_id_; } |
390 | | |
391 | | void HandleResponse(int attempt) override; |
392 | | bool SendRequest(int attempt) override; |
393 | | void UnregisterAsyncTaskCallback() override; |
394 | | |
395 | | const TabletId tablet_id_; |
396 | | const tablet::TabletDataState delete_type_; |
397 | | const boost::optional<int64_t> cas_config_opid_index_less_or_equal_; |
398 | | const std::string reason_; |
399 | | tserver::DeleteTabletResponsePB resp_; |
400 | | bool hide_only_ = false; |
401 | | }; |
402 | | |
403 | | // Send the "Alter Table" with the latest table schema to the leader replica |
404 | | // for the tablet. |
405 | | // Keeps retrying until we get an "ok" response. |
406 | | // - Alter completed |
407 | | // - Tablet has already a newer version |
408 | | // (which may happen in case of concurrent alters, or in case a previous attempt timed |
409 | | // out but was actually applied). |
410 | | class AsyncAlterTable : public AsyncTabletLeaderTask { |
411 | | public: |
412 | | AsyncAlterTable( |
413 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet) |
414 | 3.80k | : AsyncTabletLeaderTask(master, callback_pool, tablet) {} |
415 | | |
416 | | AsyncAlterTable( |
417 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet, |
418 | | const scoped_refptr<TableInfo>& table, |
419 | | const TransactionId transaction_id) |
420 | | : AsyncTabletLeaderTask(master, callback_pool, tablet, table), transaction_id_(transaction_id) |
421 | 28.0k | {} |
422 | | |
423 | 50.6k | Type type() const override { return ASYNC_ALTER_TABLE; } |
424 | | |
425 | 172k | std::string type_name() const override { return "Alter Table"; } |
426 | | |
427 | | TableType table_type() const; |
428 | | |
429 | | protected: |
430 | | uint32_t schema_version_; |
431 | | tserver::ChangeMetadataResponsePB resp_; |
432 | | |
433 | | private: |
434 | | void HandleResponse(int attempt) override; |
435 | | bool SendRequest(int attempt) override; |
436 | | |
437 | | TransactionId transaction_id_ = TransactionId::Nil(); |
438 | | }; |
439 | | |
440 | | class AsyncBackfillDone : public AsyncAlterTable { |
441 | | public: |
442 | | AsyncBackfillDone(Master* master, |
443 | | ThreadPool* callback_pool, |
444 | | const scoped_refptr<TabletInfo>& tablet, |
445 | | const std::string& table_id) |
446 | 3.80k | : AsyncAlterTable(master, callback_pool, tablet), table_id_(table_id) {} |
447 | | |
448 | 13.6k | Type type() const override { return ASYNC_BACKFILL_DONE; } |
449 | | |
450 | 30.2k | std::string type_name() const override { return "Mark backfill done."; } |
451 | | |
452 | | private: |
453 | | bool SendRequest(int attempt) override; |
454 | | |
455 | | const std::string table_id_; |
456 | | }; |
457 | | |
458 | | class AsyncCopartitionTable : public RetryingTSRpcTask { |
459 | | public: |
460 | | AsyncCopartitionTable(Master *master, |
461 | | ThreadPool* callback_pool, |
462 | | const scoped_refptr<TabletInfo>& tablet, |
463 | | const scoped_refptr<TableInfo>& table); |
464 | | |
465 | 0 | Type type() const override { return ASYNC_COPARTITION_TABLE; } |
466 | | |
467 | 0 | std::string type_name() const override { return "Copartition Table"; } |
468 | | |
469 | | std::string description() const override; |
470 | | |
471 | | private: |
472 | | TabletId tablet_id() const override; |
473 | | |
474 | | TabletServerId permanent_uuid() const; |
475 | | |
476 | | void HandleResponse(int attempt) override; |
477 | | bool SendRequest(int attempt) override; |
478 | | |
479 | | scoped_refptr<TabletInfo> tablet_; |
480 | | scoped_refptr<TableInfo> table_; |
481 | | tserver::CopartitionTableResponsePB resp_; |
482 | | }; |
483 | | |
484 | | // Send a Truncate() RPC request. |
485 | | class AsyncTruncate : public AsyncTabletLeaderTask { |
486 | | public: |
487 | | AsyncTruncate(Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet) |
488 | 57.3k | : AsyncTabletLeaderTask(master, callback_pool, tablet) {} |
489 | | |
490 | 507k | Type type() const override { return ASYNC_TRUNCATE_TABLET; } |
491 | | |
492 | | // TODO: Could move Type to the outer scope and use YB_DEFINE_ENUM for it. So type_name() could |
493 | | // be removed. |
494 | 343k | std::string type_name() const override { return "Truncate Tablet"; } |
495 | | |
496 | | protected: |
497 | | void HandleResponse(int attempt) override; |
498 | | bool SendRequest(int attempt) override; |
499 | | |
500 | | tserver::TruncateResponsePB resp_; |
501 | | }; |
502 | | |
503 | | class CommonInfoForRaftTask : public RetryingTSRpcTask { |
504 | | public: |
505 | | CommonInfoForRaftTask( |
506 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet, |
507 | | const consensus::ConsensusStatePB& cstate, const std::string& change_config_ts_uuid); |
508 | | |
509 | | ~CommonInfoForRaftTask(); |
510 | | |
511 | | TabletId tablet_id() const override; |
512 | | |
513 | 1.07k | virtual std::string change_config_ts_uuid() const { return change_config_ts_uuid_; } |
514 | | |
515 | | protected: |
516 | | // Used by SendOrReceiveData. Return's false if RPC should not be sent. |
517 | | virtual CHECKED_STATUS PrepareRequest(int attempt) = 0; |
518 | | |
519 | | TabletServerId permanent_uuid() const; |
520 | | |
521 | | const scoped_refptr<TabletInfo> tablet_; |
522 | | const consensus::ConsensusStatePB cstate_; |
523 | | |
524 | | // The uuid of the TabletServer we intend to change in the config, for example, the one we are |
525 | | // adding to a new config, or the one we intend to remove from the current config. |
526 | | // |
527 | | // This is different from the target_ts_desc_, which points to the tablet server to whom we |
528 | | // issue the ChangeConfig RPC call, which is the Leader in the case of this class, due to the |
529 | | // PickLeaderReplica set in the constructor. |
530 | | const std::string change_config_ts_uuid_; |
531 | | }; |
532 | | |
533 | | class AsyncChangeConfigTask : public CommonInfoForRaftTask { |
534 | | public: |
535 | | AsyncChangeConfigTask( |
536 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet, |
537 | | const consensus::ConsensusStatePB& cstate, const std::string& change_config_ts_uuid) |
538 | 4.66k | : CommonInfoForRaftTask(master, callback_pool, tablet, cstate, change_config_ts_uuid) {} |
539 | | |
540 | 0 | Type type() const override { return ASYNC_CHANGE_CONFIG; } |
541 | | |
542 | 0 | std::string type_name() const override { return "ChangeConfig"; } |
543 | | |
544 | | std::string description() const override; |
545 | | |
546 | | protected: |
547 | | void HandleResponse(int attempt) override; |
548 | | bool SendRequest(int attempt) override; |
549 | | |
550 | | consensus::ChangeConfigRequestPB req_; |
551 | | consensus::ChangeConfigResponsePB resp_; |
552 | | }; |
553 | | |
554 | | class AsyncAddServerTask : public AsyncChangeConfigTask { |
555 | | public: |
556 | | AsyncAddServerTask( |
557 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet, |
558 | | consensus::PeerMemberType member_type, const consensus::ConsensusStatePB& cstate, |
559 | | const std::string& change_config_ts_uuid) |
560 | | : AsyncChangeConfigTask(master, callback_pool, tablet, cstate, change_config_ts_uuid), |
561 | 2.17k | member_type_(member_type) {} |
562 | | |
563 | 5.04k | Type type() const override { return ASYNC_ADD_SERVER; } |
564 | | |
565 | 20.1k | std::string type_name() const override { return "AddServer ChangeConfig"; } |
566 | | |
567 | 2.58k | bool started_by_lb() const override { return true; } |
568 | | |
569 | | protected: |
570 | | CHECKED_STATUS PrepareRequest(int attempt) override; |
571 | | |
572 | | private: |
573 | | // PRE_VOTER or PRE_OBSERVER (for async replicas). |
574 | | consensus::PeerMemberType member_type_; |
575 | | }; |
576 | | |
577 | | // Task to remove a tablet server peer from an overly-replicated tablet config. |
578 | | class AsyncRemoveServerTask : public AsyncChangeConfigTask { |
579 | | public: |
580 | | AsyncRemoveServerTask( |
581 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet, |
582 | | const consensus::ConsensusStatePB& cstate, const std::string& change_config_ts_uuid) |
583 | 2.49k | : AsyncChangeConfigTask(master, callback_pool, tablet, cstate, change_config_ts_uuid) {} |
584 | | |
585 | 6.05k | Type type() const override { return ASYNC_REMOVE_SERVER; } |
586 | | |
587 | 21.6k | std::string type_name() const override { return "RemoveServer ChangeConfig"; } |
588 | | |
589 | 2.40k | bool started_by_lb() const override { return true; } |
590 | | |
591 | | protected: |
592 | | CHECKED_STATUS PrepareRequest(int attempt) override; |
593 | | }; |
594 | | |
595 | | // Task to step down tablet server leader and optionally to remove it from an overly-replicated |
596 | | // tablet config. |
597 | | class AsyncTryStepDown : public CommonInfoForRaftTask { |
598 | | public: |
599 | | AsyncTryStepDown( |
600 | | Master* master, |
601 | | ThreadPool* callback_pool, |
602 | | const scoped_refptr<TabletInfo>& tablet, |
603 | | const consensus::ConsensusStatePB& cstate, |
604 | | const std::string& change_config_ts_uuid, |
605 | | bool should_remove, |
606 | | const std::string& new_leader_uuid = "") |
607 | | : CommonInfoForRaftTask(master, callback_pool, tablet, cstate, change_config_ts_uuid), |
608 | | should_remove_(should_remove), |
609 | 54.0k | new_leader_uuid_(new_leader_uuid) {} |
610 | | |
611 | 50.2k | Type type() const override { return ASYNC_TRY_STEP_DOWN; } |
612 | | |
613 | 216k | std::string type_name() const override { return "Stepdown Leader"; } |
614 | | |
615 | 270k | std::string description() const override { |
616 | 270k | return "Async Leader Stepdown"; |
617 | 270k | } |
618 | | |
619 | 569 | std::string new_leader_uuid() const { return new_leader_uuid_; } |
620 | | |
621 | 54.1k | bool started_by_lb() const override { return true; } |
622 | | |
623 | | protected: |
624 | | CHECKED_STATUS PrepareRequest(int attempt) override; |
625 | | bool SendRequest(int attempt) override; |
626 | | void HandleResponse(int attempt) override; |
627 | | |
628 | | const bool should_remove_; |
629 | | const std::string new_leader_uuid_; |
630 | | consensus::LeaderStepDownRequestPB stepdown_req_; |
631 | | consensus::LeaderStepDownResponsePB stepdown_resp_; |
632 | | }; |
633 | | |
634 | | // Task to add a table to a tablet. Catalog Manager uses this task to send the request to the |
635 | | // tserver admin service. |
636 | | class AsyncAddTableToTablet : public RetryingTSRpcTask { |
637 | | public: |
638 | | AsyncAddTableToTablet( |
639 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet, |
640 | | const scoped_refptr<TableInfo>& table); |
641 | | |
642 | 119 | Type type() const override { return ASYNC_ADD_TABLE_TO_TABLET; } |
643 | | |
644 | 508 | std::string type_name() const override { return "Add Table to Tablet"; } |
645 | | |
646 | | std::string description() const override; |
647 | | |
648 | | private: |
649 | 0 | TabletId tablet_id() const override { return tablet_id_; } |
650 | | |
651 | | void HandleResponse(int attempt) override; |
652 | | bool SendRequest(int attempt) override; |
653 | | |
654 | | scoped_refptr<TabletInfo> tablet_; |
655 | | scoped_refptr<TableInfo> table_; |
656 | | const TabletId tablet_id_; |
657 | | tserver::AddTableToTabletRequestPB req_; |
658 | | tserver::AddTableToTabletResponsePB resp_; |
659 | | }; |
660 | | |
661 | | // Task to remove a table from a tablet. Catalog Manager uses this task to send the request to the |
662 | | // tserver admin service. |
663 | | class AsyncRemoveTableFromTablet : public RetryingTSRpcTask { |
664 | | public: |
665 | | AsyncRemoveTableFromTablet( |
666 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet, |
667 | | const scoped_refptr<TableInfo>& table); |
668 | | |
669 | 20 | Type type() const override { return ASYNC_REMOVE_TABLE_FROM_TABLET; } |
670 | | |
671 | 326 | std::string type_name() const override { return "Remove Table from Tablet"; } |
672 | | |
673 | | std::string description() const override; |
674 | | |
675 | | private: |
676 | 0 | TabletId tablet_id() const override { return tablet_id_; } |
677 | | |
678 | | bool SendRequest(int attempt) override; |
679 | | void HandleResponse(int attempt) override; |
680 | | |
681 | | const scoped_refptr<TableInfo> table_; |
682 | | const scoped_refptr<TabletInfo> tablet_; |
683 | | const TabletId tablet_id_; |
684 | | tserver::RemoveTableFromTabletRequestPB req_; |
685 | | tserver::RemoveTableFromTabletResponsePB resp_; |
686 | | }; |
687 | | |
688 | | class AsyncGetTabletSplitKey : public AsyncTabletLeaderTask { |
689 | | public: |
690 | | struct Data { |
691 | | const std::string& split_encoded_key; |
692 | | const std::string& split_partition_key; |
693 | | }; |
694 | | using DataCallbackType = std::function<void(const Result<Data>&)>; |
695 | | |
696 | | AsyncGetTabletSplitKey( |
697 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet, |
698 | | DataCallbackType result_cb); |
699 | | |
700 | 21 | Type type() const override { return ASYNC_GET_TABLET_SPLIT_KEY; } |
701 | | |
702 | 867 | std::string type_name() const override { return "Get Tablet Split Key"; } |
703 | | |
704 | | protected: |
705 | | void HandleResponse(int attempt) override; |
706 | | bool SendRequest(int attempt) override; |
707 | | void Finished(const Status& status) override; |
708 | | |
709 | | tserver::GetSplitKeyRequestPB req_; |
710 | | tserver::GetSplitKeyResponsePB resp_; |
711 | | DataCallbackType result_cb_; |
712 | | }; |
713 | | |
714 | | // Sends SplitTabletRequest with provided arguments to the service interface of the leader of the |
715 | | // tablet. |
716 | | class AsyncSplitTablet : public AsyncTabletLeaderTask { |
717 | | public: |
718 | | AsyncSplitTablet( |
719 | | Master* master, ThreadPool* callback_pool, const scoped_refptr<TabletInfo>& tablet, |
720 | | const std::array<TabletId, kNumSplitParts>& new_tablet_ids, |
721 | | const std::string& split_encoded_key, const std::string& split_partition_key, |
722 | | TabletSplitCompleteHandlerIf* tablet_split_complete_handler); |
723 | | |
724 | 12 | Type type() const override { return ASYNC_SPLIT_TABLET; } |
725 | | |
726 | 942 | std::string type_name() const override { return "Split Tablet"; } |
727 | | |
728 | | protected: |
729 | | void HandleResponse(int attempt) override; |
730 | | bool SendRequest(int attempt) override; |
731 | | void Finished(const Status& status) override; |
732 | | |
733 | | tablet::SplitTabletRequestPB req_; |
734 | | tserver::SplitTabletResponsePB resp_; |
735 | | TabletSplitCompleteHandlerIf* tablet_split_complete_handler_; |
736 | | }; |
737 | | |
738 | | } // namespace master |
739 | | } // namespace yb |
740 | | |
741 | | #endif // YB_MASTER_ASYNC_RPC_TASKS_H |