diff --git a/src/mock_client_context.hpp b/src/mock_client_context.hpp new file mode 100644 index 0000000..f20bfe4 --- /dev/null +++ b/src/mock_client_context.hpp @@ -0,0 +1,29 @@ +// +// Copyright (C) 2018 Codership Oy +// + +#ifndef TRREP_MOCK_CLIENT_CONTEXT_HPP +#define TRREP_MOCK_CLIENT_CONTEXT_HPP + +#include "client_context.hpp" +#include "mutex.hpp" + +namespace trrep +{ + class mock_client_context : public trrep::client_context + { + public: + mock_client_context(trrep::server_context& server_context, + const trrep::client_id& id, + enum trrep::client_context::mode mode) + : trrep::client_context(mutex_, server_context, id, mode) + // Note: Mutex is initialized only after passed + // to client_context constructor. + , mutex_() + { } + private: + trrep::default_mutex mutex_; + }; +} + +#endif // TRREP_MOCK_CLIENT_CONTEXT_HPP diff --git a/src/mock_provider_impl.hpp b/src/mock_provider.hpp similarity index 74% rename from src/mock_provider_impl.hpp rename to src/mock_provider.hpp index 248519b..c944ed4 100644 --- a/src/mock_provider_impl.hpp +++ b/src/mock_provider.hpp @@ -2,10 +2,10 @@ // Copyright (C) 2018 Codership Oy // -#ifndef TRREP_MOCK_PROVIDER_IMPL_HPP -#define TRREP_MOCK_PROVIDER_IMPL_HPP +#ifndef TRREP_MOCK_PROVIDER_HPP +#define TRREP_MOCK_PROVIDER_HPP -#include "provider_impl.hpp" +#include "provider.hpp" #include #include @@ -13,11 +13,11 @@ namespace trrep { - class mock_provider_impl : public trrep::provider_impl + class mock_provider : public trrep::provider { public: - typedef std::map, wsrep_seqno_t > bf_abort_map; - mock_provider_impl() + typedef std::map bf_abort_map; + mock_provider() : group_id_() , node_id_() , group_seqno_(0) @@ -49,8 +49,7 @@ namespace trrep trx_meta->stid.trx = ws_handle->trx_id; trx_meta->stid.conn = conn_id; - std::pair - trx_id(conn_id, ws_handle->trx_id); + wsrep_trx_id_t trx_id(ws_handle->trx_id); bf_abort_map::iterator it(bf_abort_map_.find(trx_id)); std::cerr << "bf aborted: " << (it == bf_abort_map_.end() ? "no" : "yes") << "\n"; @@ -100,28 +99,22 @@ namespace trrep // Inject BF abort event into the provider. // - // If bf_seqno equals to WSREP_SEQNO_UNDEFINED, the BF abort - // is done without ordering and the provider will return - // WSREP_TRX_FAIL to the aborted transaction. Otherwise - // WSREP_BF_ABORT is returned to the aborted transaction. - // - // @param conn_id Connection/client identifier to be aborted - // @param trx_id Trx id to be aborted // @param bf_seqno Aborter sequence number + // @param trx_id Trx id to be aborted + // @param[out] victim_seqno // - void bf_abort(wsrep_conn_id_t conn_id, - wsrep_trx_id_t trx_id, - wsrep_seqno_t bf_seqno) + wsrep_status_t bf_abort(wsrep_seqno_t bf_seqno, + wsrep_trx_id_t trx_id, + wsrep_seqno_t* victim_seqno) { - std::cerr << "bf_abort: " << conn_id << ":" << trx_id << "\n"; - assert(bf_seqno == WSREP_SEQNO_UNDEFINED || - group_seqno_ < bf_seqno); - bf_abort_map_.insert(std::make_pair(std::make_pair(conn_id, trx_id), - bf_seqno)); + std::cerr << "bf_abort: " << trx_id << "\n"; + bf_abort_map_.insert(std::make_pair(trx_id, bf_seqno)); if (bf_seqno != WSREP_SEQNO_UNDEFINED) { group_seqno_ = bf_seqno; } + *victim_seqno = WSREP_SEQNO_UNDEFINED; + return WSREP_OK; } private: wsrep_uuid_t group_id_; @@ -132,4 +125,4 @@ namespace trrep } -#endif // TRREP_MOCK_PROVIDER_IMPL_HPP +#endif // TRREP_MOCK_PROVIDER_HPP diff --git a/src/mock_server_context.hpp b/src/mock_server_context.hpp index e26c9f2..787cc21 100644 --- a/src/mock_server_context.hpp +++ b/src/mock_server_context.hpp @@ -7,7 +7,7 @@ #include "server_context.hpp" #include "mock_client_context.hpp" -#include "mock_provider_impl.hpp" +#include "mock_provider.hpp" namespace trrep @@ -19,14 +19,11 @@ namespace trrep const std::string& id, enum trrep::server_context::rollback_mode rollback_mode) : trrep::server_context(name, id, rollback_mode) - , mock_provider_impl_() - , provider_(&mock_provider_impl_) + , provider_() , last_client_id_(0) { } trrep::provider& provider() const { return provider_; } - trrep::mock_provider_impl& mock_provider() const - { return mock_provider_impl_; } trrep::client_context* local_client_context() { return new trrep::mock_client_context(*this, ++last_client_id_, @@ -40,8 +37,7 @@ namespace trrep // void on_commit(trrep::transaction_context&) { } private: - mutable trrep::mock_provider_impl mock_provider_impl_; - mutable trrep::provider provider_; + mutable trrep::mock_provider provider_; unsigned long long last_client_id_; }; } diff --git a/src/provider.hpp b/src/provider.hpp index 68deb63..88dfb03 100644 --- a/src/provider.hpp +++ b/src/provider.hpp @@ -5,7 +5,7 @@ #ifndef TRREP_PROVIDER_HPP #define TRREP_PROVIDER_HPP -#include "provider_impl.hpp" +// #include "provider_impl.hpp" #include @@ -13,39 +13,35 @@ namespace trrep { + // Abstract interface for provider implementations class provider { - public: - - // Construct a provider with give provider implementation - // - provider(provider_impl* impl) : impl_(impl) { } - int start_transaction(wsrep_ws_handle_t* wsh) - { return impl_->start_transaction(wsh); } - int append_key(wsrep_ws_handle_t* wsh, const wsrep_key_t* key) - { return impl_->append_key(wsh, key); } - int append_data(wsrep_ws_handle_t* wsh, const wsrep_buf_t* buf) - { return impl_->append_data(wsh, buf); } - wsrep_status certify(wsrep_conn_id_t conn_id, - wsrep_ws_handle_t* wsh, - uint32_t flags, wsrep_trx_meta_t* trx_meta) - { return impl_->certify(conn_id, wsh, flags, trx_meta); } - int rollback(const wsrep_trx_id_t trx_id) - { return impl_->rollback(trx_id); } - wsrep_status commit_order_enter(wsrep_ws_handle_t* wsh) - { return impl_->commit_order_enter(wsh); } - int commit_order_leave(wsrep_ws_handle_t* wsh) - { return impl_->commit_order_leave(wsh); } - int release(wsrep_ws_handle_t* wsh) - { return impl_->release(wsh); } - - // Load the provider - // @param Path to provider library or "none" to load - // dummy provider + virtual int start_transaction(wsrep_ws_handle_t*) = 0; + virtual int append_key(wsrep_ws_handle_t*, const wsrep_key_t*) = 0; + virtual int append_data(wsrep_ws_handle_t*, const wsrep_buf_t*) = 0; + virtual wsrep_status_t + certify(wsrep_conn_id_t, wsrep_ws_handle_t*, + uint32_t, + wsrep_trx_meta_t*) = 0; + //! + //! BF abort a transaction inside provider. + //! + //! @param[in] bf_seqno Seqno of the aborter transaction + //! @param[in] victim_txt Transaction identifier of the victim + //! @param[out] victim_seqno Sequence number of the victim transaction + //! or WSREP_SEQNO_UNDEFINED if the victim was not ordered + //! + //! @return wsrep_status_t + virtual wsrep_status_t bf_abort(wsrep_seqno_t bf_seqno, + wsrep_trx_id_t victim_trx, + wsrep_seqno_t* victim_seqno) = 0; + virtual int rollback(const wsrep_trx_id_t) = 0; + virtual wsrep_status commit_order_enter(wsrep_ws_handle_t*) = 0; + virtual int commit_order_leave(wsrep_ws_handle_t*) = 0; + virtual int release(wsrep_ws_handle_t*) = 0; static provider* make_provider(const std::string& provider); - private: - provider_impl* impl_; + }; } diff --git a/src/server_context.cpp b/src/server_context.cpp index 5f76570..0e48ebb 100644 --- a/src/server_context.cpp +++ b/src/server_context.cpp @@ -7,7 +7,7 @@ #include "transaction_context.hpp" // Todo: refactor into provider factory -#include "mock_provider_impl.hpp" +#include "mock_provider.hpp" #include "wsrep_provider_v26.hpp" #include @@ -64,14 +64,13 @@ int trrep::server_context::load_provider(const std::string& provider_spec) { if (provider_spec == "mock") { - provider_ = new trrep::provider(new trrep::mock_provider_impl); + provider_ = new trrep::mock_provider; } else { struct wsrep_init_args init_args; init_args.apply_cb = &apply_cb; - provider_ = new trrep::provider( - new trrep::wsrep_provider_v26(&init_args)); + provider_ = new trrep::wsrep_provider_v26(&init_args); } return 0; } diff --git a/src/transaction_context_test.cpp b/src/transaction_context_test.cpp index f7f49dd..d44040a 100644 --- a/src/transaction_context_test.cpp +++ b/src/transaction_context_test.cpp @@ -6,7 +6,6 @@ #include "mock_client_context.hpp" #include "mock_server_context.hpp" #include "provider.hpp" -#include "mock_provider_impl.hpp" #include @@ -25,11 +24,12 @@ namespace // BF abort method to abort transactions via provider void bf_abort_provider(trrep::mock_server_context& sc, - const trrep::client_context& cc, const trrep::transaction_context& tc, - wsrep_seqno_t seqno) + wsrep_seqno_t bf_seqno) { - sc.mock_provider().bf_abort(cc.id().get(), tc.id().get(), seqno); + wsrep_seqno_t victim_seqno; + sc.provider().bf_abort(bf_seqno, tc.id().get(), &victim_seqno); + (void)victim_seqno; } trrep::transaction_context applying_transaction( @@ -287,7 +287,7 @@ BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_during_before_commit_uncertified BOOST_REQUIRE(tc.id() == trrep::transaction_id(1)); BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing); - bf_abort_provider(sc, cc, tc, WSREP_SEQNO_UNDEFINED); + bf_abort_provider(sc, tc, WSREP_SEQNO_UNDEFINED); // Run before commit BOOST_REQUIRE(tc.before_commit()); @@ -330,7 +330,7 @@ BOOST_AUTO_TEST_CASE(transaction_context_1pc_bf_during_before_commit_certified) BOOST_REQUIRE(tc.id() == trrep::transaction_id(1)); BOOST_REQUIRE(tc.state() == trrep::transaction_context::s_executing); - bf_abort_provider(sc, cc, tc, 1); + bf_abort_provider(sc, tc, 1); // Run before commit BOOST_REQUIRE(tc.before_commit()); diff --git a/src/wsrep_provider_v26.hpp b/src/wsrep_provider_v26.hpp index 9a0ef63..1972482 100644 --- a/src/wsrep_provider_v26.hpp +++ b/src/wsrep_provider_v26.hpp @@ -11,7 +11,7 @@ namespace trrep { - class wsrep_provider_v26 : public trrep::provider_impl + class wsrep_provider_v26 : public trrep::provider { public: @@ -24,6 +24,9 @@ namespace trrep certify(wsrep_conn_id_t, wsrep_ws_handle_t*, uint32_t, wsrep_trx_meta_t*) { return WSREP_OK; } + wsrep_status_t bf_abort(wsrep_seqno_t, + wsrep_trx_id_t, + wsrep_seqno_t*) { return WSREP_OK; } int rollback(const wsrep_trx_id_t) { return 0; } wsrep_status commit_order_enter(wsrep_ws_handle_t*) { return WSREP_OK; } int commit_order_leave(wsrep_ws_handle_t*) { return 0; }