in src/commands/cmd_cluster.cc [148:241]
Status Parse(const std::vector<std::string> &args) override {
subcommand_ = util::ToLower(args[1]);
if (args.size() == 2 && (subcommand_ == "version" || subcommand_ == "myid")) return Status::OK();
if (subcommand_ == "setnodeid" && args_.size() == 3 && args_[2].size() == kClusterNodeIdLen) return Status::OK();
if (subcommand_ == "migrate") {
if (args.size() < 4 || args.size() > 6) return {Status::RedisParseErr, errWrongNumOfArguments};
Status s = CommandTable::ParseSlotRanges(args_[2], slot_ranges_);
if (!s.IsOK()) {
return s;
}
dst_node_id_ = args[3];
if (args.size() >= 5) {
auto sync_flag = util::ToLower(args[4]);
if (sync_flag == "async") {
sync_migrate_ = false;
if (args.size() == 6) {
return {Status::RedisParseErr, "Async migration does not support timeout"};
}
} else if (sync_flag == "sync") {
sync_migrate_ = true;
if (args.size() == 6) {
auto parse_result = ParseInt<int>(args[5], 10);
if (!parse_result) {
return {Status::RedisParseErr, "timeout is not an integer or out of range"};
}
if (*parse_result < 0) {
return {Status::RedisParseErr, errTimeoutIsNegative};
}
sync_migrate_timeout_ = *parse_result;
}
} else {
return {Status::RedisParseErr, "Invalid sync flag"};
}
}
return Status::OK();
}
if (subcommand_ == "setnodes" && args_.size() >= 4) {
nodes_str_ = args_[2];
auto parse_result = ParseInt<int64_t>(args[3], 10);
if (!parse_result) {
return {Status::RedisParseErr, "Invalid version"};
}
set_version_ = *parse_result;
if (args_.size() == 4) return Status::OK();
if (args_.size() == 5 && util::EqualICase(args_[4], "force")) {
force_ = true;
return Status::OK();
}
return {Status::RedisParseErr, "Invalid setnodes options"};
}
// CLUSTERX SETSLOT $SLOT_ID NODE $NODE_ID $VERSION
if (subcommand_ == "setslot" && args_.size() == 6) {
Status s = CommandTable::ParseSlotRanges(args_[2], slot_ranges_);
if (!s.IsOK()) {
return s;
}
if (!util::EqualICase(args_[3], "node")) {
return {Status::RedisParseErr, "Invalid setslot options"};
}
if (args_[4].size() != kClusterNodeIdLen) {
return {Status::RedisParseErr, "Invalid node id"};
}
auto parse_version = ParseInt<int64_t>(args[5], 10);
if (!parse_version) {
return {Status::RedisParseErr, errValueNotInteger};
}
if (*parse_version < 0) return {Status::RedisParseErr, "Invalid version"};
set_version_ = *parse_version;
return Status::OK();
}
return {Status::RedisParseErr, "CLUSTERX command, CLUSTERX VERSION|MYID|SETNODEID|SETNODES|SETSLOT|MIGRATE"};
}