MXS-2025 RWBackends as a vector of unique_ptr:s
For lifetime management keep RWBackends in a vector of unique_ptrs. RWSplitSession keeps the unique_ptrs very private, and provides a vector of plain pointers for all other interfaces.
This commit is contained in:
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <maxscale/backend.hh>
|
#include <maxscale/backend.hh>
|
||||||
#include <maxscale/modutil.hh>
|
#include <maxscale/modutil.hh>
|
||||||
@ -22,6 +23,17 @@
|
|||||||
namespace maxscale
|
namespace maxscale
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** Move this somewhere else */
|
||||||
|
template<typename Smart>
|
||||||
|
std::vector<typename Smart::pointer> sptr_vec_to_ptr_vec(const std::vector<Smart>& sVec)
|
||||||
|
{
|
||||||
|
std::vector<typename Smart::pointer> pVec;
|
||||||
|
std::for_each(sVec.begin(), sVec.end(), [&pVec](const Smart& smart) {
|
||||||
|
pVec.push_back(smart.get());
|
||||||
|
});
|
||||||
|
return pVec;
|
||||||
|
}
|
||||||
|
|
||||||
/** Enum for tracking client reply state */
|
/** Enum for tracking client reply state */
|
||||||
enum reply_state_t
|
enum reply_state_t
|
||||||
{
|
{
|
||||||
@ -38,7 +50,7 @@ class RWBackend;
|
|||||||
// All interfacing is now handled via RWBackend*.
|
// All interfacing is now handled via RWBackend*.
|
||||||
using PRWBackends = std::vector<RWBackend*>;
|
using PRWBackends = std::vector<RWBackend*>;
|
||||||
|
|
||||||
// Internal storage for a class containing RWBackend:s. Not used yet.
|
// Internal storage for a class containing RWBackend:s.
|
||||||
using SRWBackends = std::vector<std::unique_ptr<RWBackend>>;
|
using SRWBackends = std::vector<std::unique_ptr<RWBackend>>;
|
||||||
|
|
||||||
class RWBackend : public mxs::Backend
|
class RWBackend : public mxs::Backend
|
||||||
@ -48,7 +60,7 @@ class RWBackend : public mxs::Backend
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static PRWBackends from_servers(SERVER_REF* servers);
|
static SRWBackends from_servers(SERVER_REF* servers);
|
||||||
|
|
||||||
RWBackend(SERVER_REF* ref);
|
RWBackend(SERVER_REF* ref);
|
||||||
virtual ~RWBackend();
|
virtual ~RWBackend();
|
||||||
|
@ -253,15 +253,15 @@ ResponseStat& RWBackend::response_stat()
|
|||||||
return m_response_stat;
|
return m_response_stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRWBackends RWBackend::from_servers(SERVER_REF* servers)
|
mxs::SRWBackends RWBackend::from_servers(SERVER_REF* servers)
|
||||||
{
|
{
|
||||||
PRWBackends backends;
|
SRWBackends backends;
|
||||||
|
|
||||||
for (SERVER_REF* ref = servers; ref; ref = ref->next)
|
for (SERVER_REF* ref = servers; ref; ref = ref->next)
|
||||||
{
|
{
|
||||||
if (ref->active)
|
if (ref->active)
|
||||||
{
|
{
|
||||||
backends.push_back(new mxs::RWBackend(ref));
|
backends.emplace_back(new mxs::RWBackend(ref));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ CatSession* Cat::newSession(MXS_SESSION* pSession)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return connected ? new CatSession(pSession, this, backends) : NULL;
|
return connected ? new CatSession(pSession, this, std::move(backends)) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cat::diagnostics(DCB* dcb)
|
void Cat::diagnostics(DCB* dcb)
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
|
|
||||||
using namespace maxscale;
|
using namespace maxscale;
|
||||||
|
|
||||||
CatSession::CatSession(MXS_SESSION* session, Cat* router, PRWBackends& backends)
|
CatSession::CatSession(MXS_SESSION* session, Cat* router, mxs::SRWBackends backends)
|
||||||
: RouterSession(session)
|
: RouterSession(session)
|
||||||
, m_session(session)
|
, m_session(session)
|
||||||
, m_backends(backends)
|
, m_backends(std::move(backends))
|
||||||
, m_completed(0)
|
, m_completed(0)
|
||||||
, m_packet_num(0)
|
, m_packet_num(0)
|
||||||
, m_query(NULL)
|
, m_query(NULL)
|
||||||
@ -68,7 +68,7 @@ int32_t CatSession::routeQuery(GWBUF* pPacket)
|
|||||||
|
|
||||||
void CatSession::clientReply(GWBUF* pPacket, DCB* pDcb)
|
void CatSession::clientReply(GWBUF* pPacket, DCB* pDcb)
|
||||||
{
|
{
|
||||||
auto backend = *m_current;
|
auto& backend = *m_current;
|
||||||
mxb_assert(backend->dcb() == pDcb);
|
mxb_assert(backend->dcb() == pDcb);
|
||||||
bool send = false;
|
bool send = false;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ class CatSession : public mxs::RouterSession
|
|||||||
CatSession& operator=(const CatSession&) = delete;
|
CatSession& operator=(const CatSession&) = delete;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CatSession(MXS_SESSION* session, Cat* router, mxs::PRWBackends& backends);
|
CatSession(MXS_SESSION* session, Cat* router, mxs::SRWBackends backends);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The RouterSession instance will be deleted when a client session
|
* The RouterSession instance will be deleted when a client session
|
||||||
@ -71,10 +71,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
MXS_SESSION* m_session;
|
MXS_SESSION* m_session;
|
||||||
mxs::PRWBackends m_backends;
|
mxs::SRWBackends m_backends;
|
||||||
uint64_t m_completed;
|
uint64_t m_completed;
|
||||||
uint8_t m_packet_num;
|
uint8_t m_packet_num;
|
||||||
mxs::PRWBackends::iterator m_current;
|
mxs::SRWBackends::iterator m_current;
|
||||||
GWBUF* m_query;
|
GWBUF* m_query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +43,7 @@ void RWSplitSession::handle_connection_keepalive(RWBackend* target)
|
|||||||
/** Each heartbeat is 1/10th of a second */
|
/** Each heartbeat is 1/10th of a second */
|
||||||
int keepalive = m_config.connection_keepalive * 10;
|
int keepalive = m_config.connection_keepalive * 10;
|
||||||
|
|
||||||
for (auto it = m_backends.begin(); it != m_backends.end(); it++)
|
for (auto it = m_raw_backends.begin(); it != m_raw_backends.end(); it++)
|
||||||
{
|
{
|
||||||
RWBackend* backend = *it;
|
RWBackend* backend = *it;
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ uint32_t extract_binary_ps_id(GWBUF* buffer)
|
|||||||
|
|
||||||
bool RWSplitSession::have_connected_slaves() const
|
bool RWSplitSession::have_connected_slaves() const
|
||||||
{
|
{
|
||||||
for (const auto& b : m_backends)
|
for (const auto& b : m_raw_backends)
|
||||||
{
|
{
|
||||||
if (b->is_slave() && b->in_use())
|
if (b->is_slave() && b->in_use())
|
||||||
{
|
{
|
||||||
@ -378,7 +378,7 @@ void RWSplitSession::compress_history(mxs::SSessionCommand& sescmd)
|
|||||||
|
|
||||||
void RWSplitSession::continue_large_session_write(GWBUF* querybuf, uint32_t type)
|
void RWSplitSession::continue_large_session_write(GWBUF* querybuf, uint32_t type)
|
||||||
{
|
{
|
||||||
for (auto it = m_backends.begin(); it != m_backends.end(); it++)
|
for (auto it = m_raw_backends.begin(); it != m_raw_backends.end(); it++)
|
||||||
{
|
{
|
||||||
RWBackend* backend = *it;
|
RWBackend* backend = *it;
|
||||||
|
|
||||||
@ -446,7 +446,7 @@ bool RWSplitSession::route_session_write(GWBUF* querybuf, uint8_t command, uint3
|
|||||||
MXS_INFO("Session write, routing to all servers.");
|
MXS_INFO("Session write, routing to all servers.");
|
||||||
bool attempted_write = false;
|
bool attempted_write = false;
|
||||||
|
|
||||||
for (auto it = m_backends.begin(); it != m_backends.end(); it++)
|
for (auto it = m_raw_backends.begin(); it != m_raw_backends.end(); it++)
|
||||||
{
|
{
|
||||||
RWBackend* backend = *it;
|
RWBackend* backend = *it;
|
||||||
|
|
||||||
@ -558,7 +558,7 @@ RWBackend* RWSplitSession::get_hinted_backend(char* name)
|
|||||||
{
|
{
|
||||||
RWBackend* rval;
|
RWBackend* rval;
|
||||||
|
|
||||||
for (auto it = m_backends.begin(); it != m_backends.end(); it++)
|
for (auto it = m_raw_backends.begin(); it != m_raw_backends.end(); it++)
|
||||||
{
|
{
|
||||||
auto& backend = *it;
|
auto& backend = *it;
|
||||||
|
|
||||||
@ -579,9 +579,9 @@ RWBackend* RWSplitSession::get_slave_backend(int max_rlag)
|
|||||||
// create a list of useable backends (includes masters, function name is a bit off),
|
// create a list of useable backends (includes masters, function name is a bit off),
|
||||||
// then feed that list to compare.
|
// then feed that list to compare.
|
||||||
PRWBackends candidates;
|
PRWBackends candidates;
|
||||||
auto counts = get_slave_counts(m_backends, m_current_master);
|
auto counts = get_slave_counts(m_raw_backends, m_current_master);
|
||||||
|
|
||||||
for (auto& backend : m_backends)
|
for (auto& backend : m_raw_backends)
|
||||||
{
|
{
|
||||||
bool can_take_slave_into_use = backend->is_slave()
|
bool can_take_slave_into_use = backend->is_slave()
|
||||||
&& !backend->in_use()
|
&& !backend->in_use()
|
||||||
@ -612,7 +612,7 @@ RWBackend* RWSplitSession::get_master_backend()
|
|||||||
{
|
{
|
||||||
RWBackend* rval;
|
RWBackend* rval;
|
||||||
/** get root master from available servers */
|
/** get root master from available servers */
|
||||||
RWBackend* master = get_root_master(m_backends);
|
RWBackend* master = get_root_master(m_raw_backends);
|
||||||
|
|
||||||
if (master)
|
if (master)
|
||||||
{
|
{
|
||||||
|
@ -373,7 +373,7 @@ std::pair<int, int> get_slave_counts(PRWBackends& backends, RWBackend* master)
|
|||||||
* @return True if session can continue
|
* @return True if session can continue
|
||||||
*/
|
*/
|
||||||
bool RWSplit::select_connect_backend_servers(MXS_SESSION* session,
|
bool RWSplit::select_connect_backend_servers(MXS_SESSION* session,
|
||||||
PRWBackends& backends,
|
mxs::PRWBackends& backends,
|
||||||
mxs::RWBackend** current_master,
|
mxs::RWBackend** current_master,
|
||||||
SessionCommandList* sescmd_list,
|
SessionCommandList* sescmd_list,
|
||||||
int* expected_responses,
|
int* expected_responses,
|
||||||
|
@ -22,10 +22,11 @@ using namespace maxscale;
|
|||||||
|
|
||||||
RWSplitSession::RWSplitSession(RWSplit* instance,
|
RWSplitSession::RWSplitSession(RWSplit* instance,
|
||||||
MXS_SESSION* session,
|
MXS_SESSION* session,
|
||||||
PRWBackends backends,
|
mxs::SRWBackends backends,
|
||||||
RWBackend* master)
|
mxs::RWBackend* master)
|
||||||
: mxs::RouterSession(session)
|
: mxs::RouterSession(session)
|
||||||
, m_backends(backends)
|
, m_backends(std::move(backends))
|
||||||
|
, m_raw_backends(sptr_vec_to_ptr_vec(m_backends))
|
||||||
, m_current_master(master)
|
, m_current_master(master)
|
||||||
, m_config(instance->config())
|
, m_config(instance->config())
|
||||||
, m_nbackends(instance->service()->n_dbref)
|
, m_nbackends(instance->service()->n_dbref)
|
||||||
@ -60,7 +61,7 @@ RWSplitSession* RWSplitSession::create(RWSplit* router, MXS_SESSION* session)
|
|||||||
|
|
||||||
if (router->have_enough_servers())
|
if (router->have_enough_servers())
|
||||||
{
|
{
|
||||||
PRWBackends backends = RWBackend::from_servers(router->service()->dbref);
|
SRWBackends backends = RWBackend::from_servers(router->service()->dbref);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* At least the master must be found if the router is in the strict mode.
|
* At least the master must be found if the router is in the strict mode.
|
||||||
@ -69,14 +70,16 @@ RWSplitSession* RWSplitSession::create(RWSplit* router, MXS_SESSION* session)
|
|||||||
|
|
||||||
RWBackend* master;
|
RWBackend* master;
|
||||||
|
|
||||||
|
auto backend_ptrs = sptr_vec_to_ptr_vec(backends);
|
||||||
|
|
||||||
if (router->select_connect_backend_servers(session,
|
if (router->select_connect_backend_servers(session,
|
||||||
backends,
|
backend_ptrs,
|
||||||
&master,
|
&master,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
connection_type::ALL))
|
connection_type::ALL))
|
||||||
{
|
{
|
||||||
if ((rses = new RWSplitSession(router, session, backends, master)))
|
if ((rses = new RWSplitSession(router, session, std::move(backends), master)))
|
||||||
{
|
{
|
||||||
router->stats().n_sessions += 1;
|
router->stats().n_sessions += 1;
|
||||||
}
|
}
|
||||||
@ -106,10 +109,10 @@ void close_all_connections(PRWBackends& backends)
|
|||||||
|
|
||||||
void RWSplitSession::close()
|
void RWSplitSession::close()
|
||||||
{
|
{
|
||||||
close_all_connections(m_backends);
|
close_all_connections(m_raw_backends);
|
||||||
m_current_query.reset();
|
m_current_query.reset();
|
||||||
|
|
||||||
for (auto& backend : m_backends)
|
for (auto& backend : m_raw_backends)
|
||||||
{
|
{
|
||||||
ResponseStat& stat = backend->response_stat();
|
ResponseStat& stat = backend->response_stat();
|
||||||
|
|
||||||
@ -310,7 +313,7 @@ RWBackend* RWSplitSession::get_backend_from_dcb(DCB* dcb)
|
|||||||
{
|
{
|
||||||
mxb_assert(dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER);
|
mxb_assert(dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER);
|
||||||
|
|
||||||
for (auto it = m_backends.begin(); it != m_backends.end(); it++)
|
for (auto it = m_raw_backends.begin(); it != m_raw_backends.end(); it++)
|
||||||
{
|
{
|
||||||
RWBackend* backend = *it;
|
RWBackend* backend = *it;
|
||||||
|
|
||||||
@ -1076,7 +1079,7 @@ bool RWSplitSession::handle_error_new_connection(DCB* backend_dcb, GWBUF* errmsg
|
|||||||
*/
|
*/
|
||||||
if (m_recv_sescmd > 0 && m_config.disable_sescmd_history)
|
if (m_recv_sescmd > 0 && m_config.disable_sescmd_history)
|
||||||
{
|
{
|
||||||
for (const auto& a : m_backends)
|
for (const auto& a : m_raw_backends)
|
||||||
{
|
{
|
||||||
if (a->in_use())
|
if (a->in_use())
|
||||||
{
|
{
|
||||||
@ -1093,8 +1096,9 @@ bool RWSplitSession::handle_error_new_connection(DCB* backend_dcb, GWBUF* errmsg
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
succp = m_router->select_connect_backend_servers(ses,
|
succp = m_router->select_connect_backend_servers(ses,
|
||||||
m_backends,
|
m_raw_backends,
|
||||||
&m_current_master,
|
&m_current_master,
|
||||||
&m_sescmd_list,
|
&m_sescmd_list,
|
||||||
&m_expected_responses,
|
&m_expected_responses,
|
||||||
|
@ -131,7 +131,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make member variables private
|
// TODO: Make member variables private
|
||||||
mxs::PRWBackends m_backends; /**< List of backend servers */
|
mxs::SRWBackends m_backends; /**< Mem. management, not for use outside RWSplitSession */
|
||||||
|
mxs::PRWBackends m_raw_backends; /**< Backend pointers for use in interfaces . */
|
||||||
mxs::RWBackend* m_current_master; /**< Current master server */
|
mxs::RWBackend* m_current_master; /**< Current master server */
|
||||||
mxs::RWBackend* m_target_node; /**< The currently locked target node */
|
mxs::RWBackend* m_target_node; /**< The currently locked target node */
|
||||||
mxs::RWBackend* m_prev_target; /**< The previous target where a query was sent */
|
mxs::RWBackend* m_prev_target; /**< The previous target where a query was sent */
|
||||||
@ -172,7 +173,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
RWSplitSession(RWSplit* instance,
|
RWSplitSession(RWSplit* instance,
|
||||||
MXS_SESSION* session,
|
MXS_SESSION* session,
|
||||||
mxs::PRWBackends backends,
|
mxs::SRWBackends backends,
|
||||||
mxs::RWBackend* master);
|
mxs::RWBackend* master);
|
||||||
|
|
||||||
void process_sescmd_response(mxs::RWBackend* backend, GWBUF** ppPacket);
|
void process_sescmd_response(mxs::RWBackend* backend, GWBUF** ppPacket);
|
||||||
|
Reference in New Issue
Block a user