1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-06-16 02:01:44 +03:00
Files
wsrep-lib/src/server_context.cpp
2018-04-17 16:37:03 +03:00

111 lines
3.0 KiB
C++

//
// Copyright (C) 2018 Codership Oy <info@codership.com>
//
#include "server_context.hpp"
#include "client_context.hpp"
#include "transaction_context.hpp"
// Todo: refactor into provider factory
#include "mock_provider_impl.hpp"
#include "wsrep_provider_v26.hpp"
#include <wsrep_api.h>
#include <cassert>
namespace
{
inline bool starts_transaction(uint32_t flags)
{
return (flags & WSREP_FLAG_TRX_START);
}
inline bool commits_transaction(uint32_t flags)
{
return (flags & WSREP_FLAG_TRX_END);
}
inline bool rolls_back_transaction(uint32_t flags)
{
return (flags & WSREP_FLAG_ROLLBACK);
}
static wsrep_cb_status_t apply_cb(void* ctx,
const wsrep_ws_handle_t* wsh,
uint32_t flags,
const wsrep_buf_t* buf,
const wsrep_trx_meta_t* meta,
wsrep_bool_t* exit_loop __attribute__((unused)))
{
wsrep_cb_status_t ret(WSREP_CB_SUCCESS);
trrep::client_context* client_context(
reinterpret_cast<trrep::client_context*>(ctx));
assert(client_context);
assert(client_context->mode() == trrep::client_context::m_applier);
trrep::data data(buf->ptr, buf->len);
trrep::transaction_context transaction_context(*client_context,
*wsh,
*meta,
flags);
if (client_context->server_context().on_apply(
*client_context, transaction_context, data))
{
ret = WSREP_CB_FAILURE;
}
return ret;
}
}
int trrep::server_context::load_provider(const std::string& provider_spec)
{
if (provider_spec == "mock")
{
provider_ = new trrep::provider(new trrep::mock_provider_impl);
}
else
{
struct wsrep_init_args init_args;
init_args.apply_cb = &apply_cb;
provider_ = new trrep::provider(
new trrep::wsrep_provider_v26(&init_args));
}
return 0;
}
int trrep::server_context::on_apply(
trrep::client_context& client_context,
trrep::transaction_context& transaction_context,
const trrep::data& data)
{
int ret(0);
if (starts_transaction(transaction_context.flags()) &&
commits_transaction(transaction_context.flags()))
{
assert(transaction_context.active() == false);
transaction_context.start_transaction();
if (client_context.apply(transaction_context, data))
{
ret = 1;
}
else if (client_context.commit(transaction_context))
{
ret = 1;
}
}
else
{
// SR not implemented yet
assert(0);
}
if (ret)
{
client_context.rollback(transaction_context);
}
return ret;
}