mirror of
https://github.com/codership/wsrep-lib.git
synced 2025-07-31 18:24:25 +03:00
Client context documentation, refactoring.
This commit is contained in:
44
README.md
44
README.md
@ -199,3 +199,47 @@ Methods:
|
|||||||
* apply()
|
* apply()
|
||||||
|
|
||||||
|
|
||||||
|
# Example usage
|
||||||
|
|
||||||
|
```
|
||||||
|
class dbms_server : public trrep::server_context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Implementation
|
||||||
|
void start()
|
||||||
|
{
|
||||||
|
// Initialize server components, start accepting client connections
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class dbms_client : public trrep::client_context
|
||||||
|
{
|
||||||
|
// Implementation
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
dbms_server server(name, id);
|
||||||
|
|
||||||
|
if (server.sst_before_init())
|
||||||
|
{
|
||||||
|
server.start();
|
||||||
|
server.wait_until_state(trrep::server_context::s_joined);
|
||||||
|
|
||||||
|
}
|
||||||
|
// Initialize dbms code here
|
||||||
|
if (server.sst_before_init() == false)
|
||||||
|
{
|
||||||
|
server.start();
|
||||||
|
server.wait_until_state(trrep::server_context::s_joined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start accepting client connections
|
||||||
|
server.wait_until_state(trrep::server_context::s_synced);
|
||||||
|
|
||||||
|
// Clients can read and write here
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
@ -424,7 +424,7 @@ EXTRACT_ALL = NO
|
|||||||
# be included in the documentation.
|
# be included in the documentation.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
EXTRACT_PRIVATE = NO
|
EXTRACT_PRIVATE = YES
|
||||||
|
|
||||||
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
|
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
|
||||||
# scope will be included in the documentation.
|
# scope will be included in the documentation.
|
||||||
|
@ -74,14 +74,3 @@ int trrep::client_context::after_statement()
|
|||||||
#endif // 0
|
#endif // 0
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This should be pure virtual method, implemented by
|
|
||||||
// DBMS integration or mock classes only.
|
|
||||||
int trrep::client_context::replay(
|
|
||||||
trrep::unique_lock<trrep::mutex>& lock,
|
|
||||||
trrep::transaction_context& tc)
|
|
||||||
{
|
|
||||||
tc.state(lock, trrep::transaction_context::s_replaying);
|
|
||||||
tc.state(lock, trrep::transaction_context::s_committed);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
@ -113,67 +113,11 @@ namespace trrep
|
|||||||
s_quitting
|
s_quitting
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
virtual ~client_context() { }
|
virtual ~client_context() { }
|
||||||
|
|
||||||
/*!
|
|
||||||
* Get reference to the client mutex.
|
|
||||||
*
|
|
||||||
* \return Reference to the client mutex.
|
|
||||||
*/
|
|
||||||
trrep::mutex& mutex() { return mutex_; }
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Get server context associated the the client session.
|
|
||||||
*
|
|
||||||
* \return Reference to server context.
|
|
||||||
*/
|
|
||||||
trrep::server_context& server_context() const
|
|
||||||
{ return server_context_; }
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Get reference to the Provider which is associated
|
|
||||||
* with the client context.
|
|
||||||
*
|
|
||||||
* \return Reference to the provider.
|
|
||||||
* \throw trrep::runtime_error if no providers are associated
|
|
||||||
* with the client context.
|
|
||||||
*/
|
|
||||||
trrep::provider& provider() const;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Get Client identifier.
|
|
||||||
*
|
|
||||||
* \return Client Identifier
|
|
||||||
*/
|
|
||||||
client_id id() const { return id_; }
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Get Client mode.
|
|
||||||
*
|
|
||||||
* \todo Enforce mutex protection if called from other threads.
|
|
||||||
*
|
|
||||||
* \return Client mode.
|
|
||||||
*/
|
|
||||||
enum mode mode() const { return mode_; }
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Get Client state.
|
|
||||||
*
|
|
||||||
* \todo Enforce mutex protection if called from other threads.
|
|
||||||
*
|
|
||||||
* \return Client state
|
|
||||||
*/
|
|
||||||
enum state state() const { return state_; }
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Virtual method to return true if the client operates
|
|
||||||
* in two phase commit mode.
|
|
||||||
*
|
|
||||||
* \return True if two phase commit is required, false otherwise.
|
|
||||||
*/
|
|
||||||
virtual bool do_2pc() const = 0;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Virtual method which should be called before the client
|
* Virtual method which should be called before the client
|
||||||
* starts processing the command received from the application.
|
* starts processing the command received from the application.
|
||||||
@ -229,55 +173,50 @@ namespace trrep
|
|||||||
virtual int after_statement();
|
virtual int after_statement();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Append SR fragment to the transaction.
|
* Get reference to the client mutex.
|
||||||
|
*
|
||||||
|
* \return Reference to the client mutex.
|
||||||
*/
|
*/
|
||||||
virtual int append_fragment(trrep::transaction_context&,
|
trrep::mutex& mutex() { return mutex_; }
|
||||||
uint32_t, const trrep::data&)
|
|
||||||
{ return 0; }
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Commit the transaction.
|
* Get server context associated the the client session.
|
||||||
|
*
|
||||||
|
* \return Reference to server context.
|
||||||
*/
|
*/
|
||||||
virtual int commit(trrep::transaction_context&) = 0;
|
trrep::server_context& server_context() const
|
||||||
|
{ return server_context_; }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Rollback the transaction.
|
* Get reference to the Provider which is associated
|
||||||
|
* with the client context.
|
||||||
|
*
|
||||||
|
* \return Reference to the provider.
|
||||||
|
* \throw trrep::runtime_error if no providers are associated
|
||||||
|
* with the client context.
|
||||||
*/
|
*/
|
||||||
virtual int rollback(trrep::transaction_context&) = 0;
|
trrep::provider& provider() const;
|
||||||
|
|
||||||
virtual void will_replay(trrep::transaction_context&) { }
|
/*!
|
||||||
virtual int replay(trrep::unique_lock<trrep::mutex>&,
|
* Get Client identifier.
|
||||||
trrep::transaction_context& tc);
|
*
|
||||||
|
* \return Client Identifier
|
||||||
|
*/
|
||||||
|
client_id id() const { return id_; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get Client mode.
|
||||||
|
*
|
||||||
|
* \todo Enforce mutex protection if called from other threads.
|
||||||
|
*
|
||||||
|
* \return Client mode.
|
||||||
|
*/
|
||||||
|
enum mode mode() const { return mode_; }
|
||||||
|
|
||||||
virtual int apply(trrep::transaction_context&,
|
|
||||||
const trrep::data&) = 0;
|
|
||||||
|
|
||||||
virtual void wait_for_replayers(trrep::unique_lock<trrep::mutex>&)
|
|
||||||
{ }
|
|
||||||
virtual int prepare_data_for_replication(
|
|
||||||
const trrep::transaction_context&, trrep::data& data)
|
|
||||||
{
|
|
||||||
static const char buf[1] = { 1 };
|
|
||||||
data.assign(buf, 1);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
virtual void override_error(const trrep::client_error&) { }
|
|
||||||
virtual bool killed() const { return 0; }
|
|
||||||
virtual void abort() const { ::abort(); }
|
|
||||||
virtual void store_globals() { }
|
|
||||||
// Debug helpers
|
|
||||||
virtual void debug_sync(const std::string&)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
virtual void debug_suicide(const std::string&)
|
|
||||||
{
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
protected:
|
protected:
|
||||||
/*!
|
/*!
|
||||||
* Client context constuctor
|
* Client context constuctor. This is protected so that it
|
||||||
|
* can be called from derived class constructors only.
|
||||||
*/
|
*/
|
||||||
client_context(trrep::mutex& mutex,
|
client_context(trrep::mutex& mutex,
|
||||||
trrep::server_context& server_context,
|
trrep::server_context& server_context,
|
||||||
@ -293,6 +232,105 @@ namespace trrep
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*
|
||||||
|
* Friend declarations
|
||||||
|
*/
|
||||||
|
friend int server_context::on_apply(client_context&,
|
||||||
|
trrep::transaction_context&,
|
||||||
|
const trrep::data&);
|
||||||
|
friend class client_context_switch;
|
||||||
|
friend class transaction_context;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get Client state.
|
||||||
|
*
|
||||||
|
* \todo Enforce mutex protection if called from other threads.
|
||||||
|
*
|
||||||
|
* \return Client state
|
||||||
|
*/
|
||||||
|
enum state state() const { return state_; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Virtual method to return true if the client operates
|
||||||
|
* in two phase commit mode.
|
||||||
|
*
|
||||||
|
* \return True if two phase commit is required, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool do_2pc() const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Append SR fragment to the transaction.
|
||||||
|
*/
|
||||||
|
virtual int append_fragment(trrep::transaction_context&,
|
||||||
|
uint32_t, const trrep::data&)
|
||||||
|
{ return 0; }
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* This method applies a write set give in data buffer.
|
||||||
|
* This must be implemented by the DBMS integration.
|
||||||
|
*
|
||||||
|
* \return Zero on success, non-zero on applying failure.
|
||||||
|
*/
|
||||||
|
virtual int apply(trrep::transaction_context& transaction,
|
||||||
|
const trrep::data& data) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Virtual method which will be called
|
||||||
|
* in order to commit the transaction into
|
||||||
|
* storage engine.
|
||||||
|
*
|
||||||
|
* \return Zero on success, non-zero on failure.
|
||||||
|
*/
|
||||||
|
virtual int commit(trrep::transaction_context&) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Rollback the transaction.
|
||||||
|
*
|
||||||
|
* This metod must be implemented by DBMS integration.
|
||||||
|
*
|
||||||
|
* \return Zero on success, no-zero on failure.
|
||||||
|
*/
|
||||||
|
virtual int rollback(trrep::transaction_context&) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Notify a implementation that the client is about
|
||||||
|
* to replay the transaction.
|
||||||
|
*/
|
||||||
|
virtual void will_replay(trrep::transaction_context&) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Replay the transaction.
|
||||||
|
*/
|
||||||
|
virtual int replay(trrep::unique_lock<trrep::mutex>&,
|
||||||
|
trrep::transaction_context& tc) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Wait until all of the replaying transactions have been committed.
|
||||||
|
*/
|
||||||
|
virtual void wait_for_replayers(trrep::unique_lock<trrep::mutex>&) const = 0;
|
||||||
|
|
||||||
|
virtual int prepare_data_for_replication(
|
||||||
|
const trrep::transaction_context&, trrep::data& data)
|
||||||
|
{
|
||||||
|
static const char buf[1] = { 1 };
|
||||||
|
data.assign(buf, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual void override_error(const trrep::client_error&) = 0;
|
||||||
|
virtual bool killed() const = 0;
|
||||||
|
virtual void abort() const = 0;
|
||||||
|
virtual void store_globals() = 0;
|
||||||
|
// Debug helpers
|
||||||
|
virtual void debug_sync(const std::string&) = 0;
|
||||||
|
virtual void debug_suicide(const std::string&) = 0;
|
||||||
|
|
||||||
void state(enum state state);
|
void state(enum state state);
|
||||||
|
|
||||||
trrep::mutex& mutex_;
|
trrep::mutex& mutex_;
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "lock.hpp"
|
#include "lock.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace trrep
|
namespace trrep
|
||||||
{
|
{
|
||||||
class condition_variable
|
class condition_variable
|
||||||
@ -23,7 +25,7 @@ namespace trrep
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Default pthreads based condition variable implementation
|
// Default pthreads based condition variable implementation
|
||||||
class default_condition_variable : condition_variable
|
class default_condition_variable : public condition_variable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
default_condition_variable()
|
default_condition_variable()
|
||||||
|
@ -110,6 +110,7 @@ public:
|
|||||||
const std::string& id,
|
const std::string& id,
|
||||||
const std::string& address)
|
const std::string& address)
|
||||||
: trrep::server_context(mutex_,
|
: trrep::server_context(mutex_,
|
||||||
|
cond_,
|
||||||
name, id, address, name + "_data",
|
name, id, address, name + "_data",
|
||||||
trrep::server_context::rm_async)
|
trrep::server_context::rm_async)
|
||||||
, simulator_(simulator)
|
, simulator_(simulator)
|
||||||
@ -140,46 +141,6 @@ public:
|
|||||||
appliers_.erase(appliers_.begin());
|
appliers_.erase(appliers_.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_connect()
|
|
||||||
{
|
|
||||||
std::cerr << "dbms_server: connected" << "\n";
|
|
||||||
trrep::unique_lock<trrep::mutex> lock(mutex_);
|
|
||||||
state_ = s_connected;
|
|
||||||
cond_.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_view(const trrep::view& view)
|
|
||||||
{
|
|
||||||
std::cerr << "================================================\nView:\n"
|
|
||||||
<< "id: " << view.id() << "\n"
|
|
||||||
<< "status: " << view.status() << "\n"
|
|
||||||
<< "own_index: " << view.own_index() << "\n"
|
|
||||||
<< "final: " << view.final() << "\n"
|
|
||||||
<< "members: \n";
|
|
||||||
auto members(view.members());
|
|
||||||
for (const auto& m : members)
|
|
||||||
{
|
|
||||||
std::cerr << "id: " << m.id() << " "
|
|
||||||
<< "name: " << m.name() << "\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
std::cerr << "=================================================\n";
|
|
||||||
trrep::unique_lock<trrep::mutex> lock(mutex_);
|
|
||||||
if (view.final())
|
|
||||||
{
|
|
||||||
state_ = s_disconnected;
|
|
||||||
cond_.notify_all();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_sync()
|
|
||||||
{
|
|
||||||
std::cerr << "Synced with group" << "\n";
|
|
||||||
trrep::unique_lock<trrep::mutex> lock(mutex_);
|
|
||||||
state_ = s_synced;
|
|
||||||
cond_.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sst_before_init() const override { return false; }
|
bool sst_before_init() const override { return false; }
|
||||||
std::string on_sst_request()
|
std::string on_sst_request()
|
||||||
{
|
{
|
||||||
@ -198,32 +159,6 @@ public:
|
|||||||
provider().sst_sent(gtid, 0);
|
provider().sst_sent(gtid, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait_until_state(enum state state)
|
|
||||||
{
|
|
||||||
trrep::unique_lock<trrep::mutex> lock(mutex_);
|
|
||||||
while (state_ != state)
|
|
||||||
{
|
|
||||||
cond_.wait(lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void wait_until_connected()
|
|
||||||
{
|
|
||||||
trrep::unique_lock<trrep::mutex> lock(mutex_);
|
|
||||||
while (state_ != s_connected)
|
|
||||||
{
|
|
||||||
cond_.wait(lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wait_until_disconnected()
|
|
||||||
{
|
|
||||||
trrep::unique_lock<trrep::mutex> lock(mutex_);
|
|
||||||
while (state_ != s_disconnected)
|
|
||||||
{
|
|
||||||
cond_.wait(lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client context management
|
// Client context management
|
||||||
trrep::client_context* local_client_context();
|
trrep::client_context* local_client_context();
|
||||||
|
|
||||||
@ -277,13 +212,14 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool do_2pc() const { return false; }
|
private:
|
||||||
int apply(trrep::transaction_context&, const trrep::data&)
|
bool do_2pc() const override { return false; }
|
||||||
|
int apply(trrep::transaction_context&, const trrep::data&) override
|
||||||
{
|
{
|
||||||
// std::cerr << "applying" << "\n";
|
// std::cerr << "applying" << "\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int commit(trrep::transaction_context& transaction_context)
|
int commit(trrep::transaction_context& transaction_context) override
|
||||||
{
|
{
|
||||||
int ret(0);
|
int ret(0);
|
||||||
ret = transaction_context.before_commit();
|
ret = transaction_context.before_commit();
|
||||||
@ -292,7 +228,7 @@ public:
|
|||||||
// std::cerr << "commit" << "\n";
|
// std::cerr << "commit" << "\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int rollback(trrep::transaction_context& transaction_context)
|
int rollback(trrep::transaction_context& transaction_context) override
|
||||||
{
|
{
|
||||||
std::cerr << "rollback: " << transaction_context.id().get()
|
std::cerr << "rollback: " << transaction_context.id().get()
|
||||||
<< "state: " << trrep::to_string(transaction_context.state())
|
<< "state: " << trrep::to_string(transaction_context.state())
|
||||||
@ -301,7 +237,23 @@ public:
|
|||||||
transaction_context.after_rollback();
|
transaction_context.after_rollback();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
|
void will_replay(trrep::transaction_context&) override { }
|
||||||
|
int replay(trrep::unique_lock<trrep::mutex>& lock,
|
||||||
|
trrep::transaction_context& tc) override
|
||||||
|
{
|
||||||
|
tc.state(lock, trrep::transaction_context::s_replaying);
|
||||||
|
tc.state(lock, trrep::transaction_context::s_committed);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void wait_for_replayers(trrep::unique_lock<trrep::mutex>&) const override
|
||||||
|
{ }
|
||||||
|
void override_error(const trrep::client_error&) override { }
|
||||||
|
bool killed() const override { return false; }
|
||||||
|
void abort() const override { ::abort(); }
|
||||||
|
void store_globals() override { }
|
||||||
|
void debug_sync(const std::string&) override { }
|
||||||
|
void debug_suicide(const std::string&) override { }
|
||||||
|
|
||||||
void run_one_transaction()
|
void run_one_transaction()
|
||||||
{
|
{
|
||||||
@ -448,8 +400,7 @@ void dbms_simulator::start()
|
|||||||
throw trrep::runtime_error("Failed to connect");
|
throw trrep::runtime_error("Failed to connect");
|
||||||
}
|
}
|
||||||
server.start_applier();
|
server.start_applier();
|
||||||
server.wait_until_connected();
|
server.wait_until_state(trrep::server_context::s_synced);
|
||||||
server.wait_until_state(dbms_server::s_synced);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start client threads
|
// Start client threads
|
||||||
@ -487,7 +438,7 @@ void dbms_simulator::stop()
|
|||||||
});
|
});
|
||||||
|
|
||||||
server.provider().disconnect();
|
server.provider().disconnect();
|
||||||
server.wait_until_disconnected();
|
server.wait_until_state(trrep::server_context::s_disconnected);
|
||||||
server.stop_applier();
|
server.stop_applier();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "client_context.hpp"
|
#include "client_context.hpp"
|
||||||
#include "mutex.hpp"
|
#include "mutex.hpp"
|
||||||
|
#include "compiler.hpp"
|
||||||
|
|
||||||
namespace trrep
|
namespace trrep
|
||||||
{
|
{
|
||||||
@ -28,6 +29,25 @@ namespace trrep
|
|||||||
int commit(trrep::transaction_context&);
|
int commit(trrep::transaction_context&);
|
||||||
int rollback(trrep::transaction_context&);
|
int rollback(trrep::transaction_context&);
|
||||||
bool do_2pc() const { return do_2pc_; }
|
bool do_2pc() const { return do_2pc_; }
|
||||||
|
void will_replay(trrep::transaction_context&) TRREP_OVERRIDE { }
|
||||||
|
int replay(trrep::unique_lock<trrep::mutex>& lock,
|
||||||
|
trrep::transaction_context& tc) TRREP_OVERRIDE
|
||||||
|
{
|
||||||
|
tc.state(lock, trrep::transaction_context::s_replaying);
|
||||||
|
tc.state(lock, trrep::transaction_context::s_committed);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void wait_for_replayers(trrep::unique_lock<trrep::mutex>&) const
|
||||||
|
TRREP_OVERRIDE { }
|
||||||
|
void override_error(const trrep::client_error&) TRREP_OVERRIDE { }
|
||||||
|
bool killed() const TRREP_OVERRIDE { return false; }
|
||||||
|
void abort() const TRREP_OVERRIDE { }
|
||||||
|
void store_globals() TRREP_OVERRIDE { }
|
||||||
|
void debug_sync(const std::string&) TRREP_OVERRIDE { }
|
||||||
|
void debug_suicide(const std::string&) TRREP_OVERRIDE
|
||||||
|
{
|
||||||
|
::abort();
|
||||||
|
}
|
||||||
|
|
||||||
// Mock state modifiers
|
// Mock state modifiers
|
||||||
void fail_next_applying(bool fail_next_applying)
|
void fail_next_applying(bool fail_next_applying)
|
||||||
|
@ -19,8 +19,10 @@ namespace trrep
|
|||||||
mock_server_context(const std::string& name,
|
mock_server_context(const std::string& name,
|
||||||
const std::string& id,
|
const std::string& id,
|
||||||
enum trrep::server_context::rollback_mode rollback_mode)
|
enum trrep::server_context::rollback_mode rollback_mode)
|
||||||
: trrep::server_context(mutex_, name, id, "", "./", rollback_mode)
|
: trrep::server_context(mutex_, cond_,
|
||||||
|
name, id, "", "./", rollback_mode)
|
||||||
, mutex_()
|
, mutex_()
|
||||||
|
, cond_()
|
||||||
, provider_()
|
, provider_()
|
||||||
, last_client_id_(0)
|
, last_client_id_(0)
|
||||||
{ }
|
{ }
|
||||||
@ -47,6 +49,7 @@ namespace trrep
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
trrep::default_mutex mutex_;
|
trrep::default_mutex mutex_;
|
||||||
|
trrep::default_condition_variable cond_;
|
||||||
mutable trrep::mock_provider provider_;
|
mutable trrep::mock_provider provider_;
|
||||||
unsigned long long last_client_id_;
|
unsigned long long last_client_id_;
|
||||||
};
|
};
|
||||||
|
@ -215,6 +215,55 @@ void trrep::server_context::sst_received(const wsrep_gtid_t& gtid)
|
|||||||
provider_->sst_received(gtid, 0);
|
provider_->sst_received(gtid, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void trrep::server_context::wait_until_state(
|
||||||
|
enum trrep::server_context::state state) const
|
||||||
|
{
|
||||||
|
trrep::unique_lock<trrep::mutex> lock(mutex_);
|
||||||
|
while (state_ != state)
|
||||||
|
{
|
||||||
|
cond_.wait(lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trrep::server_context::on_connect()
|
||||||
|
{
|
||||||
|
std::cout << "Server " << name_ << " connected to cluster" << "\n";
|
||||||
|
trrep::unique_lock<trrep::mutex> lock(mutex_);
|
||||||
|
state_ = s_connected;
|
||||||
|
cond_.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void trrep::server_context::on_view(const trrep::view& view)
|
||||||
|
{
|
||||||
|
std::cout << "================================================\nView:\n"
|
||||||
|
<< "id: " << view.id() << "\n"
|
||||||
|
<< "status: " << view.status() << "\n"
|
||||||
|
<< "own_index: " << view.own_index() << "\n"
|
||||||
|
<< "final: " << view.final() << "\n"
|
||||||
|
<< "members: \n";
|
||||||
|
const std::vector<trrep::view::member>& members(view.members());
|
||||||
|
for (std::vector<trrep::view::member>::const_iterator i(members.begin());
|
||||||
|
i != members.end(); ++i)
|
||||||
|
{
|
||||||
|
std::cout << "id: " << i->id() << " "
|
||||||
|
<< "name: " << i->name() << "\n";
|
||||||
|
}
|
||||||
|
std::cout << "=================================================\n";
|
||||||
|
trrep::unique_lock<trrep::mutex> lock(mutex_);
|
||||||
|
if (view.final())
|
||||||
|
{
|
||||||
|
state_ = s_disconnected;
|
||||||
|
cond_.notify_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trrep::server_context::on_sync()
|
||||||
|
{
|
||||||
|
std::cout << "Synced with group" << "\n";
|
||||||
|
trrep::unique_lock<trrep::mutex> lock(mutex_);
|
||||||
|
state_ = s_synced;
|
||||||
|
cond_.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
int trrep::server_context::on_apply(
|
int trrep::server_context::on_apply(
|
||||||
trrep::client_context& client_context,
|
trrep::client_context& client_context,
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
|
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "mutex.hpp"
|
#include "mutex.hpp"
|
||||||
|
#include "condition_variable.hpp"
|
||||||
#include "wsrep_api.h"
|
#include "wsrep_api.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -216,37 +217,43 @@ namespace trrep
|
|||||||
return *provider_;
|
return *provider_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Virtual method which will be called when the server
|
* Virtual method which will be called when the server
|
||||||
* has been joined to the cluster. Must be provided by
|
* has been joined to the cluster. Must be provided by
|
||||||
* the implementation.
|
* the implementation.
|
||||||
*/
|
|
||||||
virtual void on_connect() = 0;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Wait until the server has connected to the cluster.
|
|
||||||
*
|
*
|
||||||
* \todo This should not be pure virtual method,
|
* \todo Document overriding.
|
||||||
* this base class should provide the server state
|
|
||||||
* machine and proper synchronization.
|
|
||||||
*/
|
*/
|
||||||
virtual void wait_until_connected() = 0;
|
virtual void on_connect();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Virtual method which will be called when a view
|
* Virtual method which will be called when a view
|
||||||
* notification event has been delivered by the
|
* notification event has been delivered by the
|
||||||
* provider.
|
* provider.
|
||||||
*
|
*
|
||||||
|
* \todo Document overriding.
|
||||||
|
*
|
||||||
* \params view trrep::view object which holds the new view
|
* \params view trrep::view object which holds the new view
|
||||||
* information.
|
* information.
|
||||||
*/
|
*/
|
||||||
virtual void on_view(const trrep::view& view) = 0;
|
virtual void on_view(const trrep::view& view);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Virtual method which will be called when the server
|
* Virtual method which will be called when the server
|
||||||
* has been synchronized with the cluster.
|
* has been synchronized with the cluster.
|
||||||
|
*
|
||||||
|
* \todo Document overriding.
|
||||||
*/
|
*/
|
||||||
virtual void on_sync() = 0;
|
virtual void on_sync();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Wait until server reaches given state.
|
||||||
|
*
|
||||||
|
* \todo Waiting for transitional states may not be reliable.
|
||||||
|
*/
|
||||||
|
void wait_until_state(trrep::server_context::state) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Virtual method to return true if the configured SST
|
* Virtual method to return true if the configured SST
|
||||||
@ -336,12 +343,15 @@ namespace trrep
|
|||||||
* \param rollback_mode Rollback mode which server operates on.
|
* \param rollback_mode Rollback mode which server operates on.
|
||||||
*/
|
*/
|
||||||
server_context(trrep::mutex& mutex,
|
server_context(trrep::mutex& mutex,
|
||||||
|
trrep::condition_variable& cond,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& id,
|
const std::string& id,
|
||||||
const std::string& address,
|
const std::string& address,
|
||||||
const std::string& working_dir,
|
const std::string& working_dir,
|
||||||
enum rollback_mode rollback_mode)
|
enum rollback_mode rollback_mode)
|
||||||
: mutex_(mutex)
|
: mutex_(mutex)
|
||||||
|
, cond_(cond)
|
||||||
|
, state_(s_disconnected)
|
||||||
, provider_()
|
, provider_()
|
||||||
, name_(name)
|
, name_(name)
|
||||||
, id_(id)
|
, id_(id)
|
||||||
@ -356,6 +366,8 @@ namespace trrep
|
|||||||
server_context& operator=(const server_context&);
|
server_context& operator=(const server_context&);
|
||||||
|
|
||||||
trrep::mutex& mutex_;
|
trrep::mutex& mutex_;
|
||||||
|
trrep::condition_variable& cond_;
|
||||||
|
enum state state_;
|
||||||
trrep::provider* provider_;
|
trrep::provider* provider_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::string id_;
|
std::string id_;
|
||||||
|
Reference in New Issue
Block a user