in katran/lib/KatranLb.cpp [1200:1279]
bool KatranLb::modifyRealsForVip(
const ModifyAction action,
const std::vector<NewReal>& reals,
const VipKey& vip) {
if (config_.disableForwarding) {
LOG(ERROR) << "delRealForVip called on non-forwarding instance";
return false;
}
UpdateReal ureal;
std::vector<UpdateReal> ureals;
ureal.action = action;
auto vip_iter = vips_.find(vip);
if (vip_iter == vips_.end()) {
LOG(INFO) << folly::sformat(
"trying to modify reals for non existing vip: {}", vip.address);
return false;
}
auto cur_reals = vip_iter->second.getReals();
for (const auto& real : reals) {
if (validateAddress(real.address) == AddressType::INVALID) {
LOG(ERROR) << "Invalid real's address: " << real.address;
continue;
}
folly::IPAddress raddr(real.address);
VLOG(4) << folly::format(
"modifying real: {} with weight {} for vip {}:{}:{}",
real.address,
real.weight,
vip.address,
vip.port,
vip.proto);
if (action == ModifyAction::DEL) {
auto real_iter = reals_.find(raddr);
if (real_iter == reals_.end()) {
LOG(INFO) << "trying to delete non-existing real";
continue;
}
if (std::find(
cur_reals.begin(), cur_reals.end(), real_iter->second.num) ==
cur_reals.end()) {
// this real doesn't belong to this vip
LOG(INFO) << folly::sformat(
"trying to delete non-existing real for the VIP: {}", vip.address);
continue;
}
ureal.updatedReal.num = real_iter->second.num;
decreaseRefCountForReal(raddr);
} else {
auto real_iter = reals_.find(raddr);
if (real_iter != reals_.end()) {
if (std::find(
cur_reals.begin(), cur_reals.end(), real_iter->second.num) ==
cur_reals.end()) {
// increment ref count if it's a new real for this vip
increaseRefCountForReal(raddr, real.flags);
cur_reals.push_back(real_iter->second.num);
}
ureal.updatedReal.num = real_iter->second.num;
} else {
auto rnum = increaseRefCountForReal(raddr, real.flags);
if (rnum == config_.maxReals) {
LOG(INFO) << "exhausted real's space";
continue;
}
ureal.updatedReal.num = rnum;
}
ureal.updatedReal.weight = real.weight;
ureal.updatedReal.hash = raddr.hash();
}
ureals.push_back(ureal);
}
auto ch_positions = vip_iter->second.batchRealsUpdate(ureals);
auto vip_num = vip_iter->second.getVipNum();
programHashRing(ch_positions, vip_num);
return true;
}