in src/meta/partition_guardian.cpp [141:224]
bool partition_guardian::from_proposals(meta_view &view,
const dsn::gpid &gpid,
configuration_proposal_action &action)
{
const partition_configuration &pc = *get_config(*(view.apps), gpid);
config_context &cc = *get_config_context(*(view.apps), gpid);
bool is_action_valid;
if (cc.lb_actions.empty()) {
action.type = config_type::CT_INVALID;
return false;
}
action = *(cc.lb_actions.front());
char reason[1024];
if (action.target.is_invalid()) {
sprintf(reason, "action target is invalid");
goto invalid_action;
}
if (action.node.is_invalid()) {
sprintf(reason, "action node is invalid");
goto invalid_action;
}
if (!is_node_alive(*(view.nodes), action.target)) {
sprintf(reason, "action target(%s) is not alive", action.target.to_string());
goto invalid_action;
}
if (!is_node_alive(*(view.nodes), action.node)) {
sprintf(reason, "action node(%s) is not alive", action.node.to_string());
goto invalid_action;
}
if (cc.lb_actions.is_abnormal_learning_proposal()) {
sprintf(reason, "learning process abnormal");
goto invalid_action;
}
switch (action.type) {
case config_type::CT_ASSIGN_PRIMARY:
is_action_valid = (action.node == action.target && pc.primary.is_invalid() &&
!is_secondary(pc, action.node));
break;
case config_type::CT_UPGRADE_TO_PRIMARY:
is_action_valid = (action.node == action.target && pc.primary.is_invalid() &&
is_secondary(pc, action.node));
break;
case config_type::CT_ADD_SECONDARY:
case config_type::CT_ADD_SECONDARY_FOR_LB:
is_action_valid = (is_primary(pc, action.target) && !is_secondary(pc, action.node));
is_action_valid = (is_action_valid && is_node_alive(*(view.nodes), action.node));
break;
case config_type::CT_DOWNGRADE_TO_INACTIVE:
case config_type::CT_REMOVE:
is_action_valid = (is_primary(pc, action.target) && is_member(pc, action.node));
break;
case config_type::CT_DOWNGRADE_TO_SECONDARY:
is_action_valid = (action.target == action.node && is_primary(pc, action.target));
break;
default:
is_action_valid = false;
break;
}
if (is_action_valid)
return true;
else
sprintf(reason, "action is invalid");
invalid_action:
std::stringstream ss;
ss << action;
LOG_INFO("proposal action({}) for gpid({}) is invalid, clear all proposal actions: {}",
ss.str(),
gpid,
reason);
action.type = config_type::CT_INVALID;
while (!cc.lb_actions.empty()) {
configuration_proposal_action cpa = *cc.lb_actions.front();
if (!cc.lb_actions.is_from_balancer()) {
finish_cure_proposal(view, gpid, cpa);
}
cc.lb_actions.pop_front();
}
return false;
}