1
0
mirror of https://github.com/codership/wsrep-lib.git synced 2025-07-21 12:22:06 +03:00

Pass victim context for provider on BF abort

This change is needed for custom provider implementations to
have a way to access the victim in the application context.

Helper interface operation_context to pass caller context for
service/provider callbacks in more type safe way.
This commit is contained in:
Teemu Ollakka
2022-05-01 16:37:24 +03:00
parent bfc5a8f6ee
commit b3f0e05da4
9 changed files with 87 additions and 11 deletions

View File

@ -43,6 +43,7 @@
#include "thread.hpp" #include "thread.hpp"
#include "xid.hpp" #include "xid.hpp"
#include "chrono.hpp" #include "chrono.hpp"
#include "operation_context.hpp"
namespace wsrep namespace wsrep
{ {
@ -662,22 +663,45 @@ namespace wsrep
* called by a transaction which needs to BF abort a conflicting * called by a transaction which needs to BF abort a conflicting
* locally processing transaction. * locally processing transaction.
*/ */
int bf_abort(wsrep::seqno bf_seqno) int bf_abort(wsrep::seqno bf_seqno,
wsrep::operation_context& victim_ctx)
{ {
wsrep::unique_lock<wsrep::mutex> lock(mutex_); wsrep::unique_lock<wsrep::mutex> lock(mutex_);
assert(mode_ == m_local || transaction_.is_streaming()); assert(mode_ == m_local || transaction_.is_streaming());
return transaction_.bf_abort(lock, bf_seqno); return transaction_.bf_abort(lock, bf_seqno, victim_ctx);
}
/**
* For backwards compatibility when the caller does not pass
* victim_ctx.
*/
int bf_abort(wsrep::seqno bf_seqno)
{
wsrep::null_operation_context victim_ctx;
return bf_abort(bf_seqno, victim_ctx);
} }
/** /**
* Brute force abort a transaction in total order. This method * Brute force abort a transaction in total order. This method
* should be called by the TOI operation which needs to * should be called by the TOI operation which needs to
* BF abort a transaction. * BF abort a transaction.
*/ */
int total_order_bf_abort(wsrep::seqno bf_seqno) int total_order_bf_abort(wsrep::seqno bf_seqno,
wsrep::operation_context& victim_ctx)
{ {
wsrep::unique_lock<wsrep::mutex> lock(mutex_); wsrep::unique_lock<wsrep::mutex> lock(mutex_);
assert(mode_ == m_local || transaction_.is_streaming()); assert(mode_ == m_local || transaction_.is_streaming());
return transaction_.total_order_bf_abort(lock, bf_seqno); return transaction_.total_order_bf_abort(lock, bf_seqno,
victim_ctx);
}
/**
* For backwards compatibility when the caller does not pass
* victim_ctx.
*/
int total_order_bf_abort(wsrep::seqno bf_seqno)
{
wsrep::null_operation_context victim_ctx;
return total_order_bf_abort(bf_seqno, victim_ctx);
} }
/** /**

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2022 Codership Oy <info@codership.com>
*
* This file is part of wsrep-lib.
*
* Wsrep-lib is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Wsrep-lib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
*/
/** @file operation_context.hpp
*
* A slightly more type safe way compared to void pointers to
* pass operation contexts through wsrep-lib to callbacks.
*/
#ifndef WSREP_OPERATION_CONTEXT_HPP
#define WSREP_OPERATION_CONTEXT_HPP
namespace wsrep
{
struct operation_context
{
virtual ~operation_context() = default;
};
struct null_operation_context : operation_context
{
};
} // namespace wsrep
#endif /* WSREP_OPERATION_CONTEXT_HPP */

View File

@ -26,6 +26,7 @@
#include "client_id.hpp" #include "client_id.hpp"
#include "transaction_id.hpp" #include "transaction_id.hpp"
#include "compiler.hpp" #include "compiler.hpp"
#include "operation_context.hpp"
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
@ -342,6 +343,7 @@ namespace wsrep
*/ */
virtual enum status bf_abort(wsrep::seqno bf_seqno, virtual enum status bf_abort(wsrep::seqno bf_seqno,
wsrep::transaction_id victim_trx, wsrep::transaction_id victim_trx,
wsrep::operation_context& victim_ctx,
wsrep::seqno& victim_seqno) = 0; wsrep::seqno& victim_seqno) = 0;
virtual enum status rollback(wsrep::transaction_id) = 0; virtual enum status rollback(wsrep::transaction_id) = 0;
virtual enum status commit_order_enter(const wsrep::ws_handle&, virtual enum status commit_order_enter(const wsrep::ws_handle&,

View File

@ -30,6 +30,7 @@
#include "buffer.hpp" #include "buffer.hpp"
#include "client_service.hpp" #include "client_service.hpp"
#include "xid.hpp" #include "xid.hpp"
#include "operation_context.hpp"
#include <cassert> #include <cassert>
#include <vector> #include <vector>
@ -199,9 +200,11 @@ namespace wsrep
void after_applying(); void after_applying();
bool bf_abort(wsrep::unique_lock<wsrep::mutex>& lock, bool bf_abort(wsrep::unique_lock<wsrep::mutex>& lock,
wsrep::seqno bf_seqno); wsrep::seqno bf_seqno,
wsrep::operation_context&);
bool total_order_bf_abort(wsrep::unique_lock<wsrep::mutex>&, bool total_order_bf_abort(wsrep::unique_lock<wsrep::mutex>&,
wsrep::seqno bf_seqno); wsrep::seqno bf_seqno,
wsrep::operation_context&);
void clone_for_replay(const wsrep::transaction& other); void clone_for_replay(const wsrep::transaction& other);

View File

@ -964,7 +964,8 @@ void wsrep::transaction::after_applying()
bool wsrep::transaction::bf_abort( bool wsrep::transaction::bf_abort(
wsrep::unique_lock<wsrep::mutex>& lock, wsrep::unique_lock<wsrep::mutex>& lock,
wsrep::seqno bf_seqno) wsrep::seqno bf_seqno,
wsrep::operation_context& victim_ctx)
{ {
bool ret(false); bool ret(false);
const enum wsrep::transaction::state state_at_enter(state()); const enum wsrep::transaction::state state_at_enter(state());
@ -989,7 +990,7 @@ bool wsrep::transaction::bf_abort(
wsrep::seqno victim_seqno; wsrep::seqno victim_seqno;
enum wsrep::provider::status enum wsrep::provider::status
status(client_state_.provider().bf_abort( status(client_state_.provider().bf_abort(
bf_seqno, id_, victim_seqno)); bf_seqno, id_, victim_ctx, victim_seqno));
switch (status) switch (status)
{ {
case wsrep::provider::success: case wsrep::provider::success:
@ -1077,9 +1078,10 @@ bool wsrep::transaction::bf_abort(
bool wsrep::transaction::total_order_bf_abort( bool wsrep::transaction::total_order_bf_abort(
wsrep::unique_lock<wsrep::mutex>& lock WSREP_UNUSED, wsrep::unique_lock<wsrep::mutex>& lock WSREP_UNUSED,
wsrep::seqno bf_seqno) wsrep::seqno bf_seqno,
wsrep::operation_context& victim_ctx)
{ {
bool ret(bf_abort(lock, bf_seqno)); bool ret(bf_abort(lock, bf_seqno, victim_ctx));
if (ret) if (ret)
{ {
bf_aborted_in_total_order_ = true; bf_aborted_in_total_order_ = true;

View File

@ -895,6 +895,7 @@ enum wsrep::provider::status
wsrep::wsrep_provider_v26::bf_abort( wsrep::wsrep_provider_v26::bf_abort(
wsrep::seqno bf_seqno, wsrep::seqno bf_seqno,
wsrep::transaction_id victim_id, wsrep::transaction_id victim_id,
wsrep::operation_context& /* Ignored here */,
wsrep::seqno& victim_seqno) wsrep::seqno& victim_seqno)
{ {
wsrep_seqno_t wsrep_victim_seqno; wsrep_seqno_t wsrep_victim_seqno;

View File

@ -63,6 +63,7 @@ namespace wsrep
enum wsrep::provider::status enum wsrep::provider::status
bf_abort(wsrep::seqno, bf_abort(wsrep::seqno,
wsrep::transaction_id, wsrep::transaction_id,
wsrep::operation_context&,
wsrep::seqno&) WSREP_OVERRIDE; wsrep::seqno&) WSREP_OVERRIDE;
enum wsrep::provider::status enum wsrep::provider::status
rollback(const wsrep::transaction_id) WSREP_OVERRIDE; rollback(const wsrep::transaction_id) WSREP_OVERRIDE;

View File

@ -310,6 +310,7 @@ namespace wsrep
enum wsrep::provider::status enum wsrep::provider::status
bf_abort(wsrep::seqno bf_seqno, bf_abort(wsrep::seqno bf_seqno,
wsrep::transaction_id trx_id, wsrep::transaction_id trx_id,
wsrep::operation_context&,
wsrep::seqno& victim_seqno) wsrep::seqno& victim_seqno)
WSREP_OVERRIDE WSREP_OVERRIDE
{ {

View File

@ -40,7 +40,8 @@ void wsrep_test::bf_abort_provider(wsrep::mock_server_state& sc,
wsrep::seqno bf_seqno) wsrep::seqno bf_seqno)
{ {
wsrep::seqno victim_seqno; wsrep::seqno victim_seqno;
sc.provider().bf_abort(bf_seqno, tc.id(), victim_seqno); wsrep::null_operation_context victim_ctx;
sc.provider().bf_abort(bf_seqno, tc.id(), victim_ctx, victim_seqno);
(void)victim_seqno; (void)victim_seqno;
} }