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:
parent
91f6f374a8
commit
0d09b56f58
@ -14,6 +14,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
#include <maxscale/backend.hh>
|
||||
#include <maxscale/modutil.hh>
|
||||
@ -22,6 +23,17 @@
|
||||
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 reply_state_t
|
||||
{
|
||||
@ -38,7 +50,7 @@ class RWBackend;
|
||||
// All interfacing is now handled via 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>>;
|
||||
|
||||
class RWBackend : public mxs::Backend
|
||||
@ -48,7 +60,7 @@ class RWBackend : public mxs::Backend
|
||||
|
||||
public:
|
||||
|
||||
static PRWBackends from_servers(SERVER_REF* servers);
|
||||
static SRWBackends from_servers(SERVER_REF* servers);
|
||||
|
||||
RWBackend(SERVER_REF* ref);
|
||||
virtual ~RWBackend();
|
||||
|
@ -253,15 +253,15 @@ ResponseStat& RWBackend::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)
|
||||
{
|
||||
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)
|
||||
|
@ -18,10 +18,10 @@
|
||||
|
||||
using namespace maxscale;
|
||||
|
||||
CatSession::CatSession(MXS_SESSION* session, Cat* router, PRWBackends& backends)
|
||||
CatSession::CatSession(MXS_SESSION* session, Cat* router, mxs::SRWBackends backends)
|
||||
: RouterSession(session)
|
||||
, m_session(session)
|
||||
, m_backends(backends)
|
||||
, m_backends(std::move(backends))
|
||||
, m_completed(0)
|
||||
, m_packet_num(0)
|
||||
, m_query(NULL)
|
||||
@ -68,7 +68,7 @@ int32_t CatSession::routeQuery(GWBUF* pPacket)
|
||||
|
||||
void CatSession::clientReply(GWBUF* pPacket, DCB* pDcb)
|
||||
{
|
||||
auto backend = *m_current;
|
||||
auto& backend = *m_current;
|
||||
mxb_assert(backend->dcb() == pDcb);
|
||||
bool send = false;
|
||||
|
||||
|
@ -27,7 +27,7 @@ class CatSession : public mxs::RouterSession
|
||||
CatSession& operator=(const CatSession&) = delete;
|
||||
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
|
||||
@ -71,10 +71,10 @@ public:
|
||||
private:
|
||||
|
||||
MXS_SESSION* m_session;
|
||||
mxs::PRWBackends m_backends;
|
||||
mxs::SRWBackends m_backends;
|
||||
uint64_t m_completed;
|
||||
uint8_t m_packet_num;
|
||||
mxs::PRWBackends::iterator m_current;
|
||||
mxs::SRWBackends::iterator m_current;
|
||||
GWBUF* m_query;
|
||||
|
||||
/**
|
||||
|
@ -43,7 +43,7 @@ void RWSplitSession::handle_connection_keepalive(RWBackend* target)
|
||||
/** Each heartbeat is 1/10th of a second */
|
||||
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;
|
||||
|
||||
@ -126,7 +126,7 @@ uint32_t extract_binary_ps_id(GWBUF* buffer)
|
||||
|
||||
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())
|
||||
{
|
||||
@ -378,7 +378,7 @@ void RWSplitSession::compress_history(mxs::SSessionCommand& sescmd)
|
||||
|
||||
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;
|
||||
|
||||
@ -446,7 +446,7 @@ bool RWSplitSession::route_session_write(GWBUF* querybuf, uint8_t command, uint3
|
||||
MXS_INFO("Session write, routing to all servers.");
|
||||
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;
|
||||
|
||||
@ -558,7 +558,7 @@ RWBackend* RWSplitSession::get_hinted_backend(char* name)
|
||||
{
|
||||
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;
|
||||
|
||||
@ -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),
|
||||
// then feed that list to compare.
|
||||
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()
|
||||
&& !backend->in_use()
|
||||
@ -612,7 +612,7 @@ RWBackend* RWSplitSession::get_master_backend()
|
||||
{
|
||||
RWBackend* rval;
|
||||
/** get root master from available servers */
|
||||
RWBackend* master = get_root_master(m_backends);
|
||||
RWBackend* master = get_root_master(m_raw_backends);
|
||||
|
||||
if (master)
|
||||
{
|
||||
|
@ -373,8 +373,8 @@ std::pair<int, int> get_slave_counts(PRWBackends& backends, RWBackend* master)
|
||||
* @return True if session can continue
|
||||
*/
|
||||
bool RWSplit::select_connect_backend_servers(MXS_SESSION* session,
|
||||
PRWBackends& backends,
|
||||
mxs::RWBackend** current_master,
|
||||
mxs::PRWBackends& backends,
|
||||
mxs::RWBackend** current_master,
|
||||
SessionCommandList* sescmd_list,
|
||||
int* expected_responses,
|
||||
connection_type type)
|
||||
|
@ -22,10 +22,11 @@ using namespace maxscale;
|
||||
|
||||
RWSplitSession::RWSplitSession(RWSplit* instance,
|
||||
MXS_SESSION* session,
|
||||
PRWBackends backends,
|
||||
RWBackend* master)
|
||||
mxs::SRWBackends backends,
|
||||
mxs::RWBackend* master)
|
||||
: 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_config(instance->config())
|
||||
, m_nbackends(instance->service()->n_dbref)
|
||||
@ -60,7 +61,7 @@ RWSplitSession* RWSplitSession::create(RWSplit* router, MXS_SESSION* session)
|
||||
|
||||
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.
|
||||
@ -69,14 +70,16 @@ RWSplitSession* RWSplitSession::create(RWSplit* router, MXS_SESSION* session)
|
||||
|
||||
RWBackend* master;
|
||||
|
||||
auto backend_ptrs = sptr_vec_to_ptr_vec(backends);
|
||||
|
||||
if (router->select_connect_backend_servers(session,
|
||||
backends,
|
||||
backend_ptrs,
|
||||
&master,
|
||||
NULL,
|
||||
NULL,
|
||||
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;
|
||||
}
|
||||
@ -106,10 +109,10 @@ void close_all_connections(PRWBackends& backends)
|
||||
|
||||
void RWSplitSession::close()
|
||||
{
|
||||
close_all_connections(m_backends);
|
||||
close_all_connections(m_raw_backends);
|
||||
m_current_query.reset();
|
||||
|
||||
for (auto& backend : m_backends)
|
||||
for (auto& backend : m_raw_backends)
|
||||
{
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
@ -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)
|
||||
{
|
||||
for (const auto& a : m_backends)
|
||||
for (const auto& a : m_raw_backends)
|
||||
{
|
||||
if (a->in_use())
|
||||
{
|
||||
@ -1093,8 +1096,9 @@ bool RWSplitSession::handle_error_new_connection(DCB* backend_dcb, GWBUF* errmsg
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
succp = m_router->select_connect_backend_servers(ses,
|
||||
m_backends,
|
||||
m_raw_backends,
|
||||
&m_current_master,
|
||||
&m_sescmd_list,
|
||||
&m_expected_responses,
|
||||
|
@ -131,7 +131,8 @@ public:
|
||||
}
|
||||
|
||||
// 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_target_node; /**< The currently locked target node */
|
||||
mxs::RWBackend* m_prev_target; /**< The previous target where a query was sent */
|
||||
@ -172,7 +173,7 @@ public:
|
||||
private:
|
||||
RWSplitSession(RWSplit* instance,
|
||||
MXS_SESSION* session,
|
||||
mxs::PRWBackends backends,
|
||||
mxs::SRWBackends backends,
|
||||
mxs::RWBackend* master);
|
||||
|
||||
void process_sescmd_response(mxs::RWBackend* backend, GWBUF** ppPacket);
|
||||
|
Loading…
x
Reference in New Issue
Block a user