| 315 | explicit KVCommandHandler(NodeData* data) : _data(data) {} |
| 316 | |
| 317 | brpc::RedisCommandHandlerResult Run(brpc::RedisConnContext* ctx, |
| 318 | const std::vector<butil::StringPiece>& args, |
| 319 | brpc::RedisReply* output, |
| 320 | bool /*flush_batched*/) override { |
| 321 | if (args.empty()) { |
| 322 | output->SetError("ERR empty command"); |
| 323 | return brpc::REDIS_CMD_HANDLED; |
| 324 | } |
| 325 | const std::string command = args[0].as_string(); |
| 326 | if (command == "ping") { |
| 327 | output->SetStatus("PONG"); |
| 328 | return brpc::REDIS_CMD_HANDLED; |
| 329 | } |
| 330 | if (command == "eval" || command == "evalsha") { |
| 331 | output->SetStatus("OK"); |
| 332 | return brpc::REDIS_CMD_HANDLED; |
| 333 | } |
| 334 | if (args.size() < 2) { |
| 335 | output->SetError("ERR wrong number of arguments"); |
| 336 | return brpc::REDIS_CMD_HANDLED; |
| 337 | } |
| 338 | |
| 339 | const std::string key = args[1].as_string(); |
| 340 | const int slot = HashSlot(key); |
| 341 | const int owner = _data->meta->OwnerOfKey(key); |
| 342 | |
| 343 | std::unordered_map<std::string, std::string>::const_iterator forced = |
| 344 | _data->meta->forced_error_by_key.find(key); |
| 345 | if (forced != _data->meta->forced_error_by_key.end()) { |
| 346 | output->SetError(forced->second); |
| 347 | return brpc::REDIS_CMD_HANDLED; |
| 348 | } |
| 349 | |
| 350 | if (!_data->meta->redirect_loop_key.empty() && |
| 351 | key == _data->meta->redirect_loop_key) { |
| 352 | const int target = 1 - _data->node_id; |
| 353 | _data->meta->moved_error_calls.fetch_add(1, std::memory_order_relaxed); |
| 354 | output->FormatError("MOVED %d %s", slot, |
| 355 | _data->meta->endpoint[target].c_str()); |
| 356 | return brpc::REDIS_CMD_HANDLED; |
| 357 | } |
| 358 | |
| 359 | bool bypass_owner_check = false; |
| 360 | if (_data->meta->enable_ask && key == _data->meta->ask_key) { |
| 361 | if (_data->node_id == _data->meta->ask_from) { |
| 362 | _data->meta->ask_error_calls.fetch_add(1, std::memory_order_relaxed); |
| 363 | output->FormatError("ASK %d %s", slot, |
| 364 | _data->meta->endpoint[_data->meta->ask_to].c_str()); |
| 365 | return brpc::REDIS_CMD_HANDLED; |
| 366 | } |
| 367 | if (_data->node_id == _data->meta->ask_to) { |
| 368 | Session* s = GetOrCreateSession(ctx); |
| 369 | if (s == NULL || !s->asking) { |
| 370 | output->SetError("ERR ASKING required"); |
| 371 | return brpc::REDIS_CMD_HANDLED; |
| 372 | } |
| 373 | s->asking = false; |
| 374 | bypass_owner_check = true; |
nothing calls this directly
no test coverage detected