From 6e2c70c22601c7ef0f6ab5339bcba4e5d773ab43 Mon Sep 17 00:00:00 2001 From: Teemu Ollakka Date: Fri, 18 Jan 2019 14:52:54 +0200 Subject: [PATCH] codership/wsrep-lib#54 Fixed race in server disconnect Convert streaming client to applier only if the server is not in disconnected state. In disconnected state the appliers map is supposed to be empty and will be reconstructed from fragment storage when the server is connected back to cluster. --- src/server_state.cpp | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/server_state.cpp b/src/server_state.cpp index 3ee042f..d8a264e 100644 --- a/src/server_state.cpp +++ b/src/server_state.cpp @@ -957,21 +957,29 @@ void wsrep::server_state::convert_streaming_client_to_applier( { streaming_clients_.erase(i); } - wsrep::high_priority_service* streaming_applier( - server_service_.streaming_applier_service( - client_state->client_service())); - streaming_applier->adopt_transaction(client_state->transaction()); - if (streaming_appliers_.insert( - std::make_pair( - std::make_pair(client_state->transaction().server_id(), - client_state->transaction().id()), - streaming_applier)).second == false) + + // Convert to applier only if the state is not disconnected. In + // disconnected state the applier map is supposed to be empty + // and it will be reconstructed from fragment storage when + // joining back to cluster. + if (state(lock) != s_disconnected) { - wsrep::log_warning() << "Could not insert streaming applier " - << id_ - << ", " - << client_state->transaction().id(); - assert(0); + wsrep::high_priority_service* streaming_applier( + server_service_.streaming_applier_service( + client_state->client_service())); + streaming_applier->adopt_transaction(client_state->transaction()); + if (streaming_appliers_.insert( + std::make_pair( + std::make_pair(client_state->transaction().server_id(), + client_state->transaction().id()), + streaming_applier)).second == false) + { + wsrep::log_warning() << "Could not insert streaming applier " + << id_ + << ", " + << client_state->transaction().id(); + assert(0); + } } }