void replica::on_group_check(const group_check_request& request, __out_param group_check_response& response) { ddebug( "%s: on_group_check from %s:%d", name(), request.config.primary.name.c_str(), request.config.primary.port ); if (request.config.ballot < get_ballot()) { response.err = ERR_VERSION_OUTDATED; return; } else if (request.config.ballot > get_ballot()) { update_local_configuration(request.config); } else if (is_same_ballot_status_change_allowed(status(), request.config.status)) { update_local_configuration(request.config, true); } switch (status()) { case PS_INACTIVE: break; case PS_SECONDARY: if (request.last_committed_decree > last_committed_decree()) { _prepare_list->commit(request.last_committed_decree, true); } break; case PS_POTENTIAL_SECONDARY: init_learn(request.learner_signature); break; case PS_ERROR: break; default: dassert (false, ""); } response.gpid = get_gpid(); response.node = primary_address(); response.err = ERR_SUCCESS; if (status() == PS_ERROR) { response.err = ERR_INVALID_STATE; } response.last_committed_decree_in_app = _app->last_committed_decree(); response.last_committed_decree_in_prepare_list = last_committed_decree(); response.learner_status_ = _potential_secondary_states.learning_status; response.learner_signature = _potential_secondary_states.learning_signature; }
bool replica::update_configuration(const partition_configuration& config) { dassert (config.ballot >= get_ballot(), ""); replica_configuration rconfig; replica_helper::get_replica_config(config, primary_address(), rconfig); if (rconfig.status == PS_PRIMARY && (rconfig.ballot > get_ballot() || status() != PS_PRIMARY) ) { _primary_states.reset_membership(config, config.primary != primary_address()); } if (config.ballot > get_ballot() || is_same_ballot_status_change_allowed(status(), rconfig.status) ) { return update_local_configuration(rconfig, true); } else return false; }
void replica::on_group_check(const group_check_request& request, /*out*/ group_check_response& response) { check_hashed_access(); ddebug( "%s: process group check, primary = %s, ballot = %" PRId64 ", status = %s, last_committed_decree = %" PRId64, name(), request.config.primary.to_string(), request.config.ballot, enum_to_string(request.config.status), request.last_committed_decree ); if (request.config.ballot < get_ballot()) { response.err = ERR_VERSION_OUTDATED; dwarn("%s: on_group_check reply %s", name(), response.err.to_string()); return; } else if (request.config.ballot > get_ballot()) { if (!update_local_configuration(request.config)) { response.err = ERR_INVALID_STATE; dwarn("%s: on_group_check reply %s", name(), response.err.to_string()); return; } } else if (is_same_ballot_status_change_allowed(status(), request.config.status)) { update_local_configuration(request.config, true); } switch (status()) { case partition_status::PS_INACTIVE: break; case partition_status::PS_SECONDARY: if (request.last_committed_decree > last_committed_decree()) { _prepare_list->commit(request.last_committed_decree, COMMIT_TO_DECREE_HARD); } break; case partition_status::PS_POTENTIAL_SECONDARY: init_learn(request.config.learner_signature); break; case partition_status::PS_ERROR: break; default: dassert (false, ""); } response.pid = get_gpid(); response.node = _stub->_primary_address; response.err = ERR_OK; if (status() == partition_status::PS_ERROR) { response.err = ERR_INVALID_STATE; dwarn("%s: on_group_check reply %s", name(), response.err.to_string()); } response.last_committed_decree_in_app = _app->last_committed_decree(); response.last_committed_decree_in_prepare_list = last_committed_decree(); response.learner_status_ = _potential_secondary_states.learning_status; response.learner_signature = _potential_secondary_states.learning_version; }