| 200 | explicit ClusterCommandHandler(ClusterMeta* meta) : _meta(meta) {} |
| 201 | |
| 202 | brpc::RedisCommandHandlerResult Run(brpc::RedisConnContext* /*ctx*/, |
| 203 | const std::vector<butil::StringPiece>& args, |
| 204 | brpc::RedisReply* output, |
| 205 | bool /*flush_batched*/) override { |
| 206 | if (args.size() < 2) { |
| 207 | output->SetError("ERR wrong number of arguments for 'cluster' command"); |
| 208 | return brpc::REDIS_CMD_HANDLED; |
| 209 | } |
| 210 | if (args[1] == "slots") { |
| 211 | _meta->slots_calls.fetch_add(1, std::memory_order_relaxed); |
| 212 | if (_meta->fail_slots) { |
| 213 | output->SetError("ERR cluster slots disabled for test"); |
| 214 | return brpc::REDIS_CMD_HANDLED; |
| 215 | } |
| 216 | |
| 217 | const int override_slot = _meta->slots_override_slot.load(std::memory_order_relaxed); |
| 218 | const int override_owner = _meta->slots_override_owner.load(std::memory_order_relaxed); |
| 219 | const int default_owner = (override_slot >= 0 && override_slot <= 16383) |
| 220 | ? OwnerBySlot(override_slot) |
| 221 | : -1; |
| 222 | if (default_owner != -1 && |
| 223 | (override_owner == 0 || override_owner == 1) && |
| 224 | override_owner != default_owner) { |
| 225 | struct SlotRange { |
| 226 | int start; |
| 227 | int end; |
| 228 | int owner; |
| 229 | SlotRange(int s, int e, int o) : start(s), end(e), owner(o) {} |
| 230 | }; |
| 231 | |
| 232 | std::vector<SlotRange> ranges; |
| 233 | if (override_slot <= kSplitSlot) { |
| 234 | if (override_slot > 0) { |
| 235 | ranges.push_back(SlotRange(0, override_slot - 1, 0)); |
| 236 | } |
| 237 | ranges.push_back(SlotRange(override_slot, override_slot, override_owner)); |
| 238 | if (override_slot < kSplitSlot) { |
| 239 | ranges.push_back(SlotRange(override_slot + 1, kSplitSlot, 0)); |
| 240 | } |
| 241 | ranges.push_back(SlotRange(kSplitSlot + 1, 16383, 1)); |
| 242 | } else { |
| 243 | ranges.push_back(SlotRange(0, kSplitSlot, 0)); |
| 244 | if (override_slot > kSplitSlot + 1) { |
| 245 | ranges.push_back(SlotRange(kSplitSlot + 1, override_slot - 1, 1)); |
| 246 | } |
| 247 | ranges.push_back(SlotRange(override_slot, override_slot, override_owner)); |
| 248 | if (override_slot < 16383) { |
| 249 | ranges.push_back(SlotRange(override_slot + 1, 16383, 1)); |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | output->SetArray(ranges.size()); |
| 254 | for (size_t i = 0; i < ranges.size(); ++i) { |
| 255 | FillSlotEntry((*output)[i], ranges[i].start, ranges[i].end, |
| 256 | _meta->endpoint[ranges[i].owner], _meta->slots_empty_host); |
| 257 | } |
| 258 | return brpc::REDIS_CMD_HANDLED; |
| 259 | } |