1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-30 07:23:07 +03:00

codership/wsrep-lib#34 Changed flow of control in sst_received()

Instead of handling error case at the beginning, execute the middle
of method body in case of success, leaving only single call to
provider().sst_received() at the end.
This commit is contained in:
Teemu Ollakka
2018-12-21 15:11:41 +02:00
parent 4f88e9aea6
commit 653d2526eb

View File

@ -528,61 +528,54 @@ void wsrep::server_state::sst_received(wsrep::client_service& cs,
wsrep::unique_lock<wsrep::mutex> lock(mutex_); wsrep::unique_lock<wsrep::mutex> lock(mutex_);
assert(state_ == s_joiner || state_ == s_initialized); assert(state_ == s_joiner || state_ == s_initialized);
// Deal with error case first. If the SST failed, the system // Run initialization only if the SST was successful.
// may be in unrecoverable state. There is no point of doing // In case of SST failure the system is in undefined state
// anything else then notifying the provider about failure // may not be recoverable.
// and returning control back to caller. if (error == 0)
if (error)
{ {
if (provider().sst_received(gtid, error)) if (server_service_.sst_before_init())
{ {
throw wsrep::runtime_error("wsrep::sst_received() failed"); if (init_initialized_ == false)
{
state(lock, s_initializing);
lock.unlock();
server_service_.debug_sync("on_view_wait_initialized");
lock.lock();
wait_until_state(lock, s_initialized);
assert(init_initialized_);
}
} }
return; state(lock, s_joined);
} lock.unlock();
if (server_service_.sst_before_init()) if (id_.is_undefined())
{
if (init_initialized_ == false)
{ {
state(lock, s_initializing); assert(0);
lock.unlock(); throw wsrep::runtime_error(
server_service_.debug_sync("on_view_wait_initialized"); "wsrep::sst_received() called before connection to cluster");
lock.lock();
wait_until_state(lock, s_initialized);
assert(init_initialized_);
} }
wsrep::view const v(server_service_.get_view(cs, id_));
wsrep::log_info() << "Recovered view from SST:\n" << v;
if (v.state_id().id() != gtid.id() ||
v.state_id().seqno() > gtid.seqno())
{
/* Since IN GENERAL we may not be able to recover SST GTID from
* the state data, we have to rely on SST script passing the GTID
* value explicitly.
* Here we check if the passed GTID makes any sense: it should
* have the same UUID and greater or equal seqno than the last
* logged view. */
std::ostringstream msg;
msg << "SST script passed bogus GTID: " << gtid
<< ". Preceeding view GTID: " << v.state_id();
throw wsrep::runtime_error(msg.str());
}
current_view_ = v;
server_service_.log_view(NULL /* this view is stored already */, v);
} }
state(lock, s_joined);
lock.unlock();
if (id_.is_undefined())
{
assert(0);
throw wsrep::runtime_error(
"wsrep::sst_received() called before connection to cluster");
}
wsrep::view const v(server_service_.get_view(cs, id_));
wsrep::log_info() << "Recovered view from SST:\n" << v;
if (v.state_id().id() != gtid.id() ||
v.state_id().seqno() > gtid.seqno())
{
/* Since IN GENERAL we may not be able to recover SST GTID from
* the state data, we have to rely on SST script passing the GTID
* value explicitly.
* Here we check if the passed GTID makes any sense: it should
* have the same UUID and greater or equal seqno than the last
* logged view. */
std::ostringstream msg;
msg << "SST script passed bogus GTID: " << gtid
<< ". Preceeding view GTID: " << v.state_id();
throw wsrep::runtime_error(msg.str());
}
current_view_ = v;
server_service_.log_view(NULL /* this view is stored already */, v);
if (provider().sst_received(gtid, error)) if (provider().sst_received(gtid, error))
{ {