1 /*
2 * Copyright (C) 2018-2019 Codership Oy <info@codership.com>
3 *
4 * This file is part of wsrep-lib.
5 *
6 * Wsrep-lib is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * Wsrep-lib is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "mock_high_priority_service.hpp"
21 #include "mock_server_state.hpp"
22 #include <sstream>
23
start_transaction(const wsrep::ws_handle & ws_handle,const wsrep::ws_meta & ws_meta)24 int wsrep::mock_high_priority_service::start_transaction(
25 const wsrep::ws_handle& ws_handle, const wsrep::ws_meta& ws_meta)
26 {
27 return client_state_->start_transaction(ws_handle, ws_meta);
28 }
29
next_fragment(const wsrep::ws_meta & ws_meta)30 int wsrep::mock_high_priority_service::next_fragment(
31 const wsrep::ws_meta& ws_meta)
32 {
33 return client_state_->next_fragment(ws_meta);
34 }
35
adopt_transaction(const wsrep::transaction & transaction)36 int wsrep::mock_high_priority_service::adopt_transaction(
37 const wsrep::transaction& transaction)
38 {
39 client_state_->adopt_transaction(transaction);
40 if (transaction.state() == wsrep::transaction::s_prepared)
41 {
42 client_state_->restore_xid(transaction.xid());
43 }
44 return 0;
45 }
46
apply_write_set(const wsrep::ws_meta & meta,const wsrep::const_buffer &,wsrep::mutable_buffer & err)47 int wsrep::mock_high_priority_service::apply_write_set(
48 const wsrep::ws_meta& meta,
49 const wsrep::const_buffer&,
50 wsrep::mutable_buffer& err)
51 {
52 assert(client_state_->toi_meta().seqno().is_undefined());
53 assert(client_state_->transaction().state() == wsrep::transaction::s_executing ||
54 client_state_->transaction().state() == wsrep::transaction::s_prepared ||
55 client_state_->transaction().state() == wsrep::transaction::s_replaying);
56 if (fail_next_applying_)
57 {
58 std::ostringstream os;
59 os << "failed " << meta;
60 err.push_back(os.str());
61 assert(err.size() > 0);
62 return 1;
63 }
64 else
65 {
66 int ret(0);
67 if (!(meta.flags() & wsrep::provider::flag::commit))
68 {
69 client_state_->fragment_applied(meta.seqno());
70 }
71 if ((meta.flags() & wsrep::provider::flag::prepare))
72 {
73 client_state_->assign_xid(wsrep::xid(1, 3, 1, "xid"));
74 ret = client_state_->before_prepare() ||
75 client_state_->after_prepare();
76 }
77 return ret;
78 };
79 }
80
commit(const wsrep::ws_handle & ws_handle,const wsrep::ws_meta & ws_meta)81 int wsrep::mock_high_priority_service::commit(
82 const wsrep::ws_handle& ws_handle,
83 const wsrep::ws_meta& ws_meta)
84 {
85 int ret(0);
86 client_state_->prepare_for_ordering(ws_handle, ws_meta, true);
87 if (do_2pc_)
88 {
89 ret = client_state_->before_prepare() ||
90 client_state_->after_prepare();
91 }
92 const bool is_ordered= !ws_meta.seqno().is_undefined();
93 if (!is_ordered)
94 {
95 client_state_->before_rollback();
96 client_state_->after_rollback();
97 return 0;
98 }
99 else
100 {
101 return (ret || client_state_->before_commit() ||
102 client_state_->ordered_commit() ||
103 client_state_->after_commit());
104 }
105 }
106
rollback(const wsrep::ws_handle & ws_handle,const wsrep::ws_meta & ws_meta)107 int wsrep::mock_high_priority_service::rollback(
108 const wsrep::ws_handle& ws_handle,
109 const wsrep::ws_meta& ws_meta)
110 {
111 client_state_->prepare_for_ordering(ws_handle, ws_meta, false);
112 return (client_state_->before_rollback() ||
113 client_state_->after_rollback());
114 }
115
apply_toi(const wsrep::ws_meta &,const wsrep::const_buffer &,wsrep::mutable_buffer &)116 int wsrep::mock_high_priority_service::apply_toi(const wsrep::ws_meta&,
117 const wsrep::const_buffer&,
118 wsrep::mutable_buffer&)
119 {
120 assert(client_state_->transaction().active() == false);
121 assert(client_state_->toi_meta().seqno().is_undefined() == false);
122 return (fail_next_toi_ ? 1 : 0);
123 }
124
apply_nbo_begin(const wsrep::ws_meta & ws_meta,const wsrep::const_buffer &,wsrep::mutable_buffer &)125 int wsrep::mock_high_priority_service::apply_nbo_begin(
126 const wsrep::ws_meta& ws_meta,
127 const wsrep::const_buffer&,
128 wsrep::mutable_buffer&)
129 {
130 const int nbo_begin_flags __attribute__((unused))
131 (wsrep::provider::flag::isolation |
132 wsrep::provider::flag::start_transaction);
133 assert(ws_meta.flags() & nbo_begin_flags);
134 assert((ws_meta.flags() & ~nbo_begin_flags) == 0);
135
136 if (fail_next_toi_)
137 {
138 return 1;
139 }
140 else
141 {
142 nbo_cs_ = std::unique_ptr<wsrep::mock_client>(
143 new wsrep::mock_client(client_state_->server_state(),
144 wsrep::client_id(1),
145 wsrep::client_state::m_local));
146 nbo_cs_->open(wsrep::client_id(1));
147 nbo_cs_->before_command();
148 nbo_cs_->before_statement();
149 return nbo_cs_->enter_nbo_mode(ws_meta);
150 }
151 }
152
adopt_apply_error(wsrep::mutable_buffer & err)153 void wsrep::mock_high_priority_service::adopt_apply_error(
154 wsrep::mutable_buffer& err)
155 {
156 client_state_->adopt_apply_error(err);
157 }
158
after_apply()159 void wsrep::mock_high_priority_service::after_apply()
160 {
161 client_state_->after_applying();
162 }
163
log_dummy_write_set(const wsrep::ws_handle &,const wsrep::ws_meta &,wsrep::mutable_buffer & err)164 int wsrep::mock_high_priority_service::log_dummy_write_set(
165 const wsrep::ws_handle&,
166 const wsrep::ws_meta&,
167 wsrep::mutable_buffer& err)
168 {
169 return err.size() > 0;
170 }
171