YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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
246k
  TSPicker() {}
73
152k
  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
158k
      : 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
1.38M
  server::MonitoredTaskState state() const override {
134
1.38M
    return state_.load(std::memory_order_acquire);
135
1.38M
  }
136
137
57.5k
  MonoTime start_timestamp() const override { return start_ts_; }
138
0
  MonoTime completion_timestamp() const override { return end_ts_; }
139
71.1k
  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
576k
      WARN_UNUSED_RESULT {
164
576k
    return state_.compare_exchange_strong(expected, new_state);
165
576k
  }
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
245k
  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
271k
  auto BindRpcCallback() {
187
271k
    return std::bind(&RetryingTSRpcTask::RpcCallback, shared_from(this));
188
271k
  }
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
29.7k
  bool RetryLimitTaskType() {
232
29.7k
    return type() != ASYNC_CREATE_REPLICA && type() != ASYNC_DELETE_REPLICA;
233
29.7k
  }
234
235
  // Returns true if we should not retry for this task type.
236
29.7k
  bool NoRetryTaskType() {
237
29.7k
    return type() == ASYNC_FLUSH_TABLETS;
238
29.7k
  }
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
158k
      permanent_uuid_(permanent_uuid) {
279
158k
  }
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
93.2k
  Type type() const override { return ASYNC_CREATE_REPLICA; }
319
320
328k
  std::string type_name() const override { return "Create Tablet"; }
321
322
  std::string description() const override;
323
324
 protected:
325
112
  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
72.6k
  Type type() const override { return START_ELECTION; }
345
346
159k
  std::string type_name() const override { return "Hinted Leader Start Election"; }
347
348
  std::string description() const override;
349
350
 protected:
351
28
  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
47.9k
        reason_(std::move(reason)) {}
377
378
156k
  Type type() const override { return ASYNC_DELETE_REPLICA; }
379
380
197k
  std::string type_name() const override { return "Delete Tablet"; }
381
382
  std::string description() const override;
383
384
0
  void set_hide_only(bool value) {
385
0
    hide_only_ = value;
386
0
  }
387
388
 protected:
389
1.10k
  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
2.50k
      : 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
18.3k
      {}
422
423
8.86k
  Type type() const override { return ASYNC_ALTER_TABLE; }
424
425
110k
  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
2.50k
      : AsyncAlterTable(master, callback_pool, tablet), table_id_(table_id) {}
447
448
16.9k
  Type type() const override { return ASYNC_BACKFILL_DONE; }
449
450
24.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
53.7k
      : AsyncTabletLeaderTask(master, callback_pool, tablet) {}
489
490
497k
  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
321k
  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
516
  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
2.16k
      : 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
1.04k
        member_type_(member_type) {}
562
563
2.31k
  Type type() const override { return ASYNC_ADD_SERVER; }
564
565
9.30k
  std::string type_name() const override { return "AddServer ChangeConfig"; }
566
567
1.20k
  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
1.11k
      : AsyncChangeConfigTask(master, callback_pool, tablet, cstate, change_config_ts_uuid) {}
584
585
3.23k
  Type type() const override { return ASYNC_REMOVE_SERVER; }
586
587
10.0k
  std::string type_name() const override { return "RemoveServer ChangeConfig"; }
588
589
1.10k
  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
5.81k
        new_leader_uuid_(new_leader_uuid) {}
610
611
6.36k
  Type type() const override { return ASYNC_TRY_STEP_DOWN; }
612
613
23.2k
  std::string type_name() const override { return "Stepdown Leader"; }
614
615
29.1k
  std::string description() const override {
616
29.1k
    return "Async Leader Stepdown";
617
29.1k
  }
618
619
96
  std::string new_leader_uuid() const { return new_leader_uuid_; }
620
621
5.84k
  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
29
  Type type() const override { return ASYNC_ADD_TABLE_TO_TABLET; }
643
644
112
  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
0
  Type type() const override { return ASYNC_REMOVE_TABLE_FROM_TABLET; }
670
671
60
  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
18
  Type type() const override { return ASYNC_GET_TABLET_SPLIT_KEY; }
701
702
279
  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
3
  Type type() const override { return ASYNC_SPLIT_TABLET; }
725
726
287
  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