1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-28 20:02:00 +03:00
- fixed node ID assertion in on_connect() method,
   fixed "sanity checks" to allow reconnection to primary component
 - fixed code duplication in on_view() method
This commit is contained in:
Alexey Yurchenko
2018-11-23 16:46:38 +02:00
parent d95ec7ed99
commit 3950ea3027
3 changed files with 43 additions and 25 deletions

View File

@ -597,6 +597,9 @@ namespace wsrep
// Close transactions when handling disconnect from the group.
void close_transactions_at_disconnect(wsrep::high_priority_service&);
// Common actions on final view
void go_final(wsrep::unique_lock<wsrep::mutex>&,
const wsrep::view&, wsrep::high_priority_service*);
wsrep::mutex& mutex_;
wsrep::condition_variable& cond_;

View File

@ -591,25 +591,36 @@ wsrep::server_state::causal_read(int timeout) const
void wsrep::server_state::on_connect(const wsrep::view& view)
{
// Sanity checks
if (id_.is_undefined() == false)
{
wsrep::log_warning() << "Unexpected connection in connected state. "
<< "Received view: " << view
<< "Previous ID: " << id_;
assert(0);
}
if (view.own_index() < 0 ||
size_t(view.own_index()) >= view.members().size())
{
std::ostringstream os;
os << "Invalid view on connect: own index out of range: " << view;
#ifndef NDEBUG
wsrep::log_error() << os.str();
assert(0);
#endif
throw wsrep::runtime_error(os.str());
}
id_ = view.members()[view.own_index()].id();
if (id_.is_undefined() == false &&
id_ != view.members()[view.own_index()].id())
{
std::ostringstream os;
os << "Connection in connected state.\n"
<< "Connected view:\n" << view
<< "Previous view:\n" << current_view_
<< "Current own ID: " << id_;
#ifndef NDEBUG
wsrep::log_error() << os.str();
assert(0);
#endif
throw wsrep::runtime_error(os.str());
}
else
{
id_ = view.members()[view.own_index()].id();
}
wsrep::log_info() << "Server "
<< name_
@ -623,6 +634,20 @@ void wsrep::server_state::on_connect(const wsrep::view& view)
state(lock, s_connected);
}
void wsrep::server_state::go_final(wsrep::unique_lock<wsrep::mutex>& lock,
const wsrep::view& view,
wsrep::high_priority_service* hps)
{
assert(view.final());
assert(hps);
if (hps)
{
close_transactions_at_disconnect(*hps);
}
state(lock, s_disconnected);
id_ = wsrep::id::undefined();
}
void wsrep::server_state::on_view(const wsrep::view& view,
wsrep::high_priority_service* high_priority_service)
{
@ -730,13 +755,7 @@ void wsrep::server_state::on_view(const wsrep::view& view,
wsrep::log_info() << "Non-primary view";
if (view.final())
{
assert(high_priority_service);
if (high_priority_service)
{
close_transactions_at_disconnect(*high_priority_service);
}
id_ = id::undefined();
state(lock, s_disconnected);
go_final(lock, view, high_priority_service);
}
else if (state_ != s_disconnecting)
{
@ -745,15 +764,8 @@ void wsrep::server_state::on_view(const wsrep::view& view,
}
else
{
assert(view.final());
assert(high_priority_service);
if (high_priority_service)
{
close_transactions_at_disconnect(*high_priority_service);
}
wsrep::unique_lock<wsrep::mutex> lock(mutex_);
state(lock, s_disconnected);
id_ = wsrep::id::undefined();
go_final(lock, view, high_priority_service);
}
server_service_.log_view(high_priority_service, view);

View File

@ -347,9 +347,12 @@ namespace
assert(app_ctx);
wsrep::server_state& server_state(
*reinterpret_cast<wsrep::server_state*>(app_ctx));
assert(server_state.id().is_undefined());
wsrep::view view(view_from_native(*view_info, server_state.id()));
assert(view.own_index() >= 0);
assert(// first connect
server_state.id().is_undefined() ||
// reconnect to primary component
server_state.id() == view.members()[view.own_index()].id());
try
{
server_state.on_connect(view);