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

Refactored storage service out of client service interface.

This commit is contained in:
Teemu Ollakka
2018-07-07 18:06:37 +03:00
parent a8be09161c
commit 2ac13100f7
31 changed files with 465 additions and 247 deletions

View File

@ -52,3 +52,11 @@ std::ostream& wsrep::operator<<(std::ostream& os, const wsrep::id& id)
return (os << uuid_str);
}
}
std::istream& wsrep::operator>>(std::istream& is, wsrep::id& id)
{
std::string id_str;
std::getline(is, id_str);
id = wsrep::id(id_str);
return is;
}

View File

@ -576,6 +576,10 @@ void wsrep::server_state::on_sync()
case s_joiner:
state(lock, s_initializing);
break;
case s_donor:
state(lock, s_joined);
state(lock, s_synced);
break;
case s_initialized:
state(lock, s_joined);
// fall through

View File

@ -5,6 +5,7 @@
#include "wsrep/transaction.hpp"
#include "wsrep/client_state.hpp"
#include "wsrep/server_state.hpp"
#include "wsrep/storage_service.hpp"
#include "wsrep/high_priority_service.hpp"
#include "wsrep/key.hpp"
#include "wsrep/logger.hpp"
@ -20,6 +21,65 @@
else wsrep::log_debug() << msg; \
} while (0)
namespace
{
class storage_service_deleter
{
public:
storage_service_deleter(wsrep::server_service& server_service)
: server_service_(server_service)
{ }
void operator()(wsrep::storage_service* storage_service)
{
server_service_.release_storage_service(storage_service);
}
private:
wsrep::server_service& server_service_;
};
template <class D>
class scoped_storage_service
{
public:
scoped_storage_service(wsrep::client_service& client_service,
wsrep::storage_service* storage_service,
D deleter)
: client_service_(client_service)
, storage_service_(storage_service)
, deleter_(deleter)
{
if (storage_service_ == 0)
{
throw wsrep::runtime_error("Null client_state provided");
}
client_service_.reset_globals();
storage_service_->store_globals();
}
wsrep::storage_service& storage_service()
{
return *storage_service_;
}
~scoped_storage_service()
{
storage_service_->reset_globals();
client_service_.store_globals();
deleter_(storage_service_);
}
private:
scoped_storage_service(const scoped_storage_service&);
scoped_storage_service& operator=(const scoped_storage_service&);
wsrep::client_service& client_service_;
wsrep::storage_service* storage_service_;
D deleter_;
};
}
// Public
wsrep::transaction::transaction(
@ -94,6 +154,20 @@ int wsrep::transaction::start_transaction(
return 0;
}
int wsrep::transaction::prepare_for_fragment_ordering(
const wsrep::ws_handle& ws_handle,
const wsrep::ws_meta& ws_meta,
bool is_commit)
{
assert(active());
ws_handle_ = ws_handle;
ws_meta_ = ws_meta;
certified_ = is_commit;
return 0;
}
int wsrep::transaction::start_replaying(const wsrep::ws_meta& ws_meta)
{
ws_meta_ = ws_meta;
@ -745,25 +819,32 @@ int wsrep::transaction::certify_fragment(
return 1;
}
// Client context to store fragment in separate transaction
// Switch temporarily to sr_transaction, switch back
// to original when this goes out of scope
wsrep::scoped_client_state<wsrep::client_deleter> sr_client_state_scope(
server_service_.local_client_state(),
wsrep::client_deleter(server_service_));
wsrep::client_state& sr_client_state(
sr_client_state_scope.client_state());
wsrep::client_state_switch client_state_switch(
client_state_,
sr_client_state);
// The rest of this method will be executed in storage service
// scope.
scoped_storage_service<storage_service_deleter>
sr_scope(
client_service_,
server_service_.storage_service(client_service_),
storage_service_deleter(server_service_));
wsrep::storage_service& storage_service(
sr_scope.storage_service());
wsrep::unique_lock<wsrep::mutex> sr_lock(sr_client_state.mutex());
wsrep::transaction& sr_transaction(
sr_client_state.transaction_);
sr_transaction.state(sr_lock, s_certifying);
sr_lock.unlock();
if (sr_client_state.client_service().append_fragment(
sr_transaction, flags_,
// First the fragment is appended to the stable storage.
// This is done to ensure that there is enough capacity
// available to store the fragment. The fragment meta data
// is updated after certification.
if (storage_service.start_transaction())
{
lock.lock();
state(lock, s_must_abort);
client_state_.override_error(wsrep::e_append_fragment_error);
return 1;
}
if (storage_service.append_fragment(
client_state_.server_state().id(),
client_state_.id(),
flags_,
wsrep::const_buffer(data.data(), data.size())))
{
lock.lock();
@ -774,30 +855,22 @@ int wsrep::transaction::certify_fragment(
enum wsrep::provider::status
cert_ret(provider().certify(client_state_.id().get(),
sr_transaction.ws_handle_,
flags_,
sr_transaction.ws_meta_));
ws_handle_,
flags_,
ws_meta_));
int ret(0);
switch (cert_ret)
{
case wsrep::provider::success:
streaming_context_.certified(sr_transaction.ws_meta().seqno());
sr_lock.lock();
sr_transaction.certified_ = true;
sr_transaction.state(sr_lock, s_committing);
sr_lock.unlock();
if (sr_client_state.client_service().commit(
sr_transaction.ws_handle(), sr_transaction.ws_meta()))
streaming_context_.certified(ws_meta_.seqno());
if (storage_service.commit(ws_handle_, ws_meta_))
{
ret = 1;
}
break;
default:
sr_lock.lock();
sr_transaction.state(sr_lock, s_must_abort);
sr_lock.unlock();
sr_client_state.client_service().bf_rollback();
storage_service.rollback(ws_handle_, ws_meta_);
ret = 1;
break;
}