diff --git a/dbsim/db_server_service.cpp b/dbsim/db_server_service.cpp index 16472c4..605fcab 100644 --- a/dbsim/db_server_service.cpp +++ b/dbsim/db_server_service.cpp @@ -75,6 +75,14 @@ void db::server_service::log_view(const wsrep::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) { throw wsrep::not_implemented_error(); diff --git a/dbsim/db_server_service.hpp b/dbsim/db_server_service.hpp index 4bc9fc3..c34fe4b 100644 --- a/dbsim/db_server_service.hpp +++ b/dbsim/db_server_service.hpp @@ -29,6 +29,8 @@ namespace db void log_dummy_write_set(wsrep::client_state&, const wsrep::ws_meta&) 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; void debug_sync(const char*) override; private: diff --git a/include/wsrep/client_state.hpp b/include/wsrep/client_state.hpp index 2199016..01a74e2 100644 --- a/include/wsrep/client_state.hpp +++ b/include/wsrep/client_state.hpp @@ -17,6 +17,7 @@ #define WSREP_CLIENT_STATE_HPP #include "server_state.hpp" +#include "server_service.hpp" #include "provider.hpp" #include "transaction.hpp" #include "client_id.hpp" @@ -807,6 +808,20 @@ namespace wsrep 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 scoped_client_state { diff --git a/include/wsrep/server_service.hpp b/include/wsrep/server_service.hpp index 83966b9..155ff45 100644 --- a/include/wsrep/server_service.hpp +++ b/include/wsrep/server_service.hpp @@ -14,6 +14,7 @@ #define WSREP_SERVER_SERVICE_HPP #include "logger.hpp" +#include "server_state.hpp" #include @@ -93,6 +94,20 @@ namespace wsrep */ 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 * performed before DBMS storage engine initialization. diff --git a/include/wsrep/server_state.hpp b/include/wsrep/server_state.hpp index f02ac80..26be715 100644 --- a/include/wsrep/server_state.hpp +++ b/include/wsrep/server_state.hpp @@ -69,7 +69,6 @@ #include "mutex.hpp" #include "condition_variable.hpp" -#include "server_service.hpp" #include "id.hpp" #include "view.hpp" #include "transaction_id.hpp" @@ -87,7 +86,7 @@ namespace wsrep class client_state; class transaction; class const_buffer; - + class server_service; /** @class Server Context * * @@ -469,7 +468,9 @@ namespace wsrep return state_; } - + /** + * Get provider status variables. + */ std::vector status() const; /** @@ -586,19 +587,6 @@ namespace wsrep 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( enum wsrep::server_state::state state) diff --git a/src/server_state.cpp b/src/server_state.cpp index 665eb23..625fe0f 100644 --- a/src/server_state.cpp +++ b/src/server_state.cpp @@ -3,6 +3,7 @@ // #include "wsrep/server_state.hpp" +#include "wsrep/server_service.hpp" #include "wsrep/high_priority_service.hpp" #include "wsrep/transaction.hpp" #include "wsrep/view.hpp" @@ -15,34 +16,6 @@ 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 // ways to bootstrap the cluster. Bootstrap happens if @@ -255,15 +228,7 @@ wsrep::server_state::~server_state() std::vector wsrep::server_state::status() const { - typedef wsrep::provider::status_variable sv; - std::vector ret(provider_->status()); - wsrep::unique_lock 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; + return provider_->status(); } @@ -493,6 +458,7 @@ void wsrep::server_state::on_view(const wsrep::view& view) << "name: " << i->name(); } wsrep::log_info() << "================================================="; + server_service_.log_view(view); current_view_ = view; if (view.status() == wsrep::view::primary) { @@ -590,7 +556,6 @@ void wsrep::server_state::on_view(const wsrep::view& view) wsrep::unique_lock lock(mutex_); state(lock, s_disconnected); } - server_service_.log_view(view); } void wsrep::server_state::on_sync() @@ -754,10 +719,11 @@ void wsrep::server_state::state( if (allowed[state_][state]) { - wsrep::log_info() << "server " << name_ << " state change: " - << to_c_string(state_) << " -> " - << to_c_string(state); + wsrep::log_debug() << "server " << name_ << " state change: " + << to_c_string(state_) << " -> " + << to_c_string(state); state_hist_.push_back(state_); + server_service_.log_state_change(state_, state); state_ = state; cond_.notify_all(); while (state_waiters_[state_]) diff --git a/src/transaction.cpp b/src/transaction.cpp index c8cd372..984a3ba 100644 --- a/src/transaction.cpp +++ b/src/transaction.cpp @@ -841,7 +841,12 @@ int wsrep::transaction::certify_commit( if (client_service_.prepare_data_for_replication()) { 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) { state(lock, s_must_abort); diff --git a/test/mock_server_state.hpp b/test/mock_server_state.hpp index 2bbeb2b..0d69f01 100644 --- a/test/mock_server_state.hpp +++ b/test/mock_server_state.hpp @@ -6,6 +6,7 @@ #define WSREP_MOCK_SERVER_CONTEXT_HPP #include "wsrep/server_state.hpp" +#include "wsrep/server_service.hpp" #include "mock_client_state.hpp" #include "mock_high_priority_service.hpp" #include "mock_provider.hpp" @@ -84,7 +85,9 @@ namespace wsrep { } 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 { return sst_before_init_; } std::string sst_request() WSREP_OVERRIDE { return ""; }