|
19 | 19 | #include "net/src/dispatch_thread.h" |
20 | 20 | #include "net/src/worker_thread.h" |
21 | 21 | #include "src/pstd/include/scope_record_lock.h" |
| 22 | +#include <future> |
22 | 23 |
|
23 | 24 | #include "rocksdb/perf_context.h" |
24 | 25 | #include "rocksdb/iostats_context.h" |
@@ -55,6 +56,8 @@ std::shared_ptr<Cmd> PikaClientConn::DoCmd(const PikaCmdArgsType& argv, const st |
55 | 56 | c_ptr->SetConn(shared_from_this()); |
56 | 57 | c_ptr->SetResp(resp_ptr); |
57 | 58 |
|
| 59 | + LOG(INFO) << "PikaClientConn::DoCmd command: " << c_ptr->name() << ", keys: " << c_ptr->current_key().size(); |
| 60 | + |
58 | 61 | // Check authed |
59 | 62 | if (AuthRequired()) { // the user is not authed, need to do auth |
60 | 63 | if (!(c_ptr->flag() & kCmdFlagsNoAuth)) { |
@@ -357,14 +360,64 @@ void PikaClientConn::DoBackgroundTask(void* arg) { |
357 | 360 | } |
358 | 361 |
|
359 | 362 | void PikaClientConn::BatchExecRedisCmd(const std::vector<net::RedisCmdArgsType>& argvs, bool cache_miss_in_rtc) { |
360 | | - resp_num.store(static_cast<int32_t>(argvs.size())); |
361 | | - for (const auto& argv : argvs) { |
362 | | - std::shared_ptr<std::string> resp_ptr = std::make_shared<std::string>(); |
363 | | - resp_array.push_back(resp_ptr); |
364 | | - ExecRedisCmd(argv, resp_ptr, cache_miss_in_rtc); |
| 363 | + if (argvs.empty()) { |
| 364 | + return; |
365 | 365 | } |
366 | | - time_stat_->process_done_ts_ = pstd::NowMicros(); |
367 | | - TryWriteResp(); |
| 366 | + if (argvs.size() > 1) { |
| 367 | + auto task = std::make_shared<ParallelTask>(); |
| 368 | + task->total_tasks = argvs.size(); |
| 369 | + task->resps.resize(argvs.size()); |
| 370 | + |
| 371 | + for (size_t i = 0; i < argvs.size(); ++i) { |
| 372 | + task->resps[i] = std::make_shared<std::string>(); |
| 373 | + std::promise<void> promise; |
| 374 | + task->futures.push_back(promise.get_future()); |
| 375 | + |
| 376 | + g_pika_server->ScheduleClientPool(&PikaClientConn::ParallelExecRedisCmd, new std::tuple(shared_from_this(), argvs[i], task, i, std::move(promise), cache_miss_in_rtc), false, false); |
| 377 | + } |
| 378 | + |
| 379 | + for (auto& f : task->futures) { |
| 380 | + f.get(); |
| 381 | + } |
| 382 | + |
| 383 | + for (const auto& resp : task->resps) { |
| 384 | + WriteResp(*resp); |
| 385 | + } |
| 386 | + if (write_completed_cb_) { |
| 387 | + write_completed_cb_(); |
| 388 | + write_completed_cb_ = nullptr; |
| 389 | + } |
| 390 | + NotifyEpoll(true); |
| 391 | + } else { |
| 392 | + resp_num.store(static_cast<int32_t>(argvs.size())); |
| 393 | + for (const auto& argv : argvs) { |
| 394 | + std::shared_ptr<std::string> resp_ptr = std::make_shared<std::string>(); |
| 395 | + resp_array.push_back(resp_ptr); |
| 396 | + ExecRedisCmd(argv, resp_ptr, cache_miss_in_rtc); |
| 397 | + } |
| 398 | + time_stat_->process_done_ts_ = pstd::NowMicros(); |
| 399 | + TryWriteResp(); |
| 400 | + } |
| 401 | +} |
| 402 | + |
| 403 | +void PikaClientConn::ParallelExecRedisCmd(void* arg) { |
| 404 | + auto* task_args = static_cast<std::tuple<std::shared_ptr<PikaClientConn>, net::RedisCmdArgsType, std::shared_ptr<ParallelTask>, size_t, std::promise<void>, bool>*>(arg); |
| 405 | + auto [conn, argv, task, index, promise, cache_miss_in_rtc] = std::move(*task_args); |
| 406 | + delete task_args; |
| 407 | + |
| 408 | + std::string opt = argv[0]; |
| 409 | + pstd::StringToLower(opt); |
| 410 | + if (opt == kClusterPrefix) { |
| 411 | + if (argv.size() >= 2) { |
| 412 | + opt += argv[1]; |
| 413 | + pstd::StringToLower(opt); |
| 414 | + } |
| 415 | + } |
| 416 | + |
| 417 | + std::shared_ptr<Cmd> cmd_ptr = conn->DoCmd(argv, opt, task->resps[index], cache_miss_in_rtc); |
| 418 | + *(task->resps[index]) = std::move(cmd_ptr->res().message()); |
| 419 | + |
| 420 | + promise.set_value(); |
368 | 421 | } |
369 | 422 |
|
370 | 423 | bool PikaClientConn::ReadCmdInCache(const net::RedisCmdArgsType& argv, const std::string& opt) { |
|
0 commit comments