1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-06-14 15:02:27 +03:00

Defined log_state_change() interface in server_service.

The interface method can be used to notify the DBMS implementation
about state changes in well defined order. The call will be done
under server_state mutex protection.
This commit is contained in:
Teemu Ollakka
2018-07-05 12:45:22 +03:00
parent fcefe9f03b
commit d80a69fe90
8 changed files with 61 additions and 59 deletions

View File

@ -75,6 +75,14 @@ void db::server_service::log_view(const wsrep::view&)
wsrep::log_info() << "View"; wsrep::log_info() << "View";
} }
void db::server_service::log_state_change(
enum wsrep::server_state::state prev_state,
enum wsrep::server_state::state current_state)
{
wsrep::log_info() << "State changed "
<< prev_state << " -> " << current_state;
}
int db::server_service::wait_committing_transactions(int) int db::server_service::wait_committing_transactions(int)
{ {
throw wsrep::not_implemented_error(); throw wsrep::not_implemented_error();

View File

@ -29,6 +29,8 @@ namespace db
void log_dummy_write_set(wsrep::client_state&, const wsrep::ws_meta&) void log_dummy_write_set(wsrep::client_state&, const wsrep::ws_meta&)
override; override;
void log_view(const wsrep::view&) override; void log_view(const wsrep::view&) override;
void log_state_change(enum wsrep::server_state::state,
enum wsrep::server_state::state) override;
int wait_committing_transactions(int) override; int wait_committing_transactions(int) override;
void debug_sync(const char*) override; void debug_sync(const char*) override;
private: private:

View File

@ -17,6 +17,7 @@
#define WSREP_CLIENT_STATE_HPP #define WSREP_CLIENT_STATE_HPP
#include "server_state.hpp" #include "server_state.hpp"
#include "server_service.hpp"
#include "provider.hpp" #include "provider.hpp"
#include "transaction.hpp" #include "transaction.hpp"
#include "client_id.hpp" #include "client_id.hpp"
@ -807,6 +808,20 @@ namespace wsrep
enum wsrep::client_state::mode orig_mode_; enum wsrep::client_state::mode orig_mode_;
}; };
class client_deleter
{
public:
client_deleter(wsrep::server_service& server_service)
: server_service_(server_service)
{ }
void operator()(wsrep::client_state* client_state)
{
server_service_.release_client_state(client_state);
}
private:
wsrep::server_service& server_service_;
};
template <class D> template <class D>
class scoped_client_state class scoped_client_state
{ {

View File

@ -14,6 +14,7 @@
#define WSREP_SERVER_SERVICE_HPP #define WSREP_SERVER_SERVICE_HPP
#include "logger.hpp" #include "logger.hpp"
#include "server_state.hpp"
#include <string> #include <string>
@ -93,6 +94,20 @@ namespace wsrep
*/ */
virtual void log_view(const wsrep::view&) = 0; virtual void log_view(const wsrep::view&) = 0;
/**
* Log a state change event.
*
* Note that this method may be called with server_state
* mutex locked, so calling server_state public methods
* should be avoided from within this call.
*
* @param prev_state Previous state server was in
* @param current_state Current state
*/
virtual void log_state_change(
enum wsrep::server_state::state prev_state,
enum wsrep::server_state::state current_state) = 0;
/** /**
* Determine if the configured SST method requires SST to be * Determine if the configured SST method requires SST to be
* performed before DBMS storage engine initialization. * performed before DBMS storage engine initialization.

View File

@ -69,7 +69,6 @@
#include "mutex.hpp" #include "mutex.hpp"
#include "condition_variable.hpp" #include "condition_variable.hpp"
#include "server_service.hpp"
#include "id.hpp" #include "id.hpp"
#include "view.hpp" #include "view.hpp"
#include "transaction_id.hpp" #include "transaction_id.hpp"
@ -87,7 +86,7 @@ namespace wsrep
class client_state; class client_state;
class transaction; class transaction;
class const_buffer; class const_buffer;
class server_service;
/** @class Server Context /** @class Server Context
* *
* *
@ -469,7 +468,9 @@ namespace wsrep
return state_; return state_;
} }
/**
* Get provider status variables.
*/
std::vector<wsrep::provider::status_variable> status() const; std::vector<wsrep::provider::status_variable> status() const;
/** /**
@ -586,19 +587,6 @@ namespace wsrep
int debug_log_level_; int debug_log_level_;
}; };
class client_deleter
{
public:
client_deleter(wsrep::server_service& server_service)
: server_service_(server_service)
{ }
void operator()(wsrep::client_state* client_state)
{
server_service_.release_client_state(client_state);
}
private:
wsrep::server_service& server_service_;
};
static inline const char* to_c_string( static inline const char* to_c_string(
enum wsrep::server_state::state state) enum wsrep::server_state::state state)

View File

@ -3,6 +3,7 @@
// //
#include "wsrep/server_state.hpp" #include "wsrep/server_state.hpp"
#include "wsrep/server_service.hpp"
#include "wsrep/high_priority_service.hpp" #include "wsrep/high_priority_service.hpp"
#include "wsrep/transaction.hpp" #include "wsrep/transaction.hpp"
#include "wsrep/view.hpp" #include "wsrep/view.hpp"
@ -15,34 +16,6 @@
namespace namespace
{ {
std::string cluster_status_string(enum wsrep::server_state::state state)
{
switch (state)
{
case wsrep::server_state::s_joined:
case wsrep::server_state::s_synced:
return "Primary";
default:
return "non-Primary";
}
}
std::string cluster_size_string(enum wsrep::server_state::state state,
const wsrep::view& current_view)
{
std::ostringstream oss;
oss << current_view.members().size();
return oss.str();
}
std::string local_index_string(enum wsrep::server_state::state state,
const wsrep::view& current_view)
{
std::ostringstream oss;
oss << current_view.own_index();
return oss.str();
}
// //
// This method is used to deal with historical burden of several // This method is used to deal with historical burden of several
// ways to bootstrap the cluster. Bootstrap happens if // ways to bootstrap the cluster. Bootstrap happens if
@ -255,15 +228,7 @@ wsrep::server_state::~server_state()
std::vector<wsrep::provider::status_variable> std::vector<wsrep::provider::status_variable>
wsrep::server_state::status() const wsrep::server_state::status() const
{ {
typedef wsrep::provider::status_variable sv; return provider_->status();
std::vector<sv> ret(provider_->status());
wsrep::unique_lock<wsrep::mutex> lock(mutex_);
ret.push_back(sv("cluster_status", cluster_status_string(state_)));
ret.push_back(sv("cluster_size",
cluster_size_string(state_, current_view_)));
ret.push_back(sv("local_index",
local_index_string(state_, current_view_)));
return ret;
} }
@ -493,6 +458,7 @@ void wsrep::server_state::on_view(const wsrep::view& view)
<< "name: " << i->name(); << "name: " << i->name();
} }
wsrep::log_info() << "================================================="; wsrep::log_info() << "=================================================";
server_service_.log_view(view);
current_view_ = view; current_view_ = view;
if (view.status() == wsrep::view::primary) if (view.status() == wsrep::view::primary)
{ {
@ -590,7 +556,6 @@ void wsrep::server_state::on_view(const wsrep::view& view)
wsrep::unique_lock<wsrep::mutex> lock(mutex_); wsrep::unique_lock<wsrep::mutex> lock(mutex_);
state(lock, s_disconnected); state(lock, s_disconnected);
} }
server_service_.log_view(view);
} }
void wsrep::server_state::on_sync() void wsrep::server_state::on_sync()
@ -754,10 +719,11 @@ void wsrep::server_state::state(
if (allowed[state_][state]) if (allowed[state_][state])
{ {
wsrep::log_info() << "server " << name_ << " state change: " wsrep::log_debug() << "server " << name_ << " state change: "
<< to_c_string(state_) << " -> " << to_c_string(state_) << " -> "
<< to_c_string(state); << to_c_string(state);
state_hist_.push_back(state_); state_hist_.push_back(state_);
server_service_.log_state_change(state_, state);
state_ = state; state_ = state;
cond_.notify_all(); cond_.notify_all();
while (state_waiters_[state_]) while (state_waiters_[state_])

View File

@ -841,7 +841,12 @@ int wsrep::transaction::certify_commit(
if (client_service_.prepare_data_for_replication()) if (client_service_.prepare_data_for_replication())
{ {
lock.lock(); lock.lock();
client_state_.override_error(wsrep::e_size_exceeded_error); // Here we fake that the size exceeded error came from provider,
// even though it came from the client service. This requires
// some consideration how to get meaningful error codes from
// the client service.
client_state_.override_error(wsrep::e_size_exceeded_error,
wsrep::provider::error_size_exceeded);
if (state_ != s_must_abort) if (state_ != s_must_abort)
{ {
state(lock, s_must_abort); state(lock, s_must_abort);

View File

@ -6,6 +6,7 @@
#define WSREP_MOCK_SERVER_CONTEXT_HPP #define WSREP_MOCK_SERVER_CONTEXT_HPP
#include "wsrep/server_state.hpp" #include "wsrep/server_state.hpp"
#include "wsrep/server_service.hpp"
#include "mock_client_state.hpp" #include "mock_client_state.hpp"
#include "mock_high_priority_service.hpp" #include "mock_high_priority_service.hpp"
#include "mock_provider.hpp" #include "mock_provider.hpp"
@ -84,7 +85,9 @@ namespace wsrep
{ {
} }
void log_view(const wsrep::view&) { } void log_view(const wsrep::view&) { }
void log_state_change(enum wsrep::server_state::state,
enum wsrep::server_state::state)
{ }
bool sst_before_init() const WSREP_OVERRIDE bool sst_before_init() const WSREP_OVERRIDE
{ return sst_before_init_; } { return sst_before_init_; }
std::string sst_request() WSREP_OVERRIDE { return ""; } std::string sst_request() WSREP_OVERRIDE { return ""; }