Files
MaxScale/server/modules/routing/smartrouter/smartsession.hh
Niclas Antti 190c0ac634 MXS-2437 Base router for Smart Router.
This is the base for Smart Router. Review and TODO comments are in the
code. This commit will be squashed several times so don't pay attention to this
specific commit message. I will add and remove TODO's in the code, rather
than save them in git commits. RBCommons will contain the history.
2019-06-10 14:40:39 +03:00

112 lines
3.8 KiB
C++

/*
* Copyright (c) 2019 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2022-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#pragma once
#include "smartrouter.hh"
#include <maxsql/packet_tracker.hh>
#include <maxscale/queryclassifier.hh>
#include <maxbase/host.hh>
#include <iostream>
class SmartRouter;
/** Currently SmartRouter is configured like this (star means many):
* SmartRouter -*> ServerAsService -> MaxscaleRouter -*> Server
* For the time being the limitation is that the tail router must be RWSplit.
* This will change once we implement it so that SmartRouter can call the tail router directly.
* Although the assumption is one RowServer and one ColumnServer, the code does not assume that,
* it simply forces you to state which Cluster is the master.
* Currently SmartRouter fails if any Cluster fails. That need not be the case, Clusters could
* be marked "is_critical" meaning non-crititcal non-masters, could be allowed to fail.
*/
class SmartRouterSession : public mxs::RouterSession, private mxs::QueryClassifier::Handler
{
public:
static SmartRouterSession* create(SmartRouter* pRouter, MXS_SESSION* pSession);
virtual ~SmartRouterSession();
SmartRouterSession(const SmartRouterSession&) = delete;
SmartRouterSession& operator=(const SmartRouterSession&) = delete;
int routeQuery(GWBUF* pBuf);
void close();
void clientReply(GWBUF* pPacket, DCB* pDcb);
void handleError(GWBUF* pPacket,
DCB* pProblem,
mxs_error_action_t action,
bool* pSuccess);
private:
enum class Mode {Idle, Query, CollectResults}; // MeasureQuery
/** struct Cluster represents a cluster of mariadb servers as a Maxscale internal Server.
* TODO In the next iteration a directly callable "Thing" should be implemented (Router, Backend
* Server - the terms are overused and confusing, maybe a new thing called MariaDB).
*/
struct Cluster
{
Cluster(SERVER_REF* b, DCB* pDcb, bool is_master)
: host {b->server->address, b->server->port}
, pBackend(b)
, pDcb(pDcb)
, is_master(is_master)
{
}
Cluster(const Cluster&) = delete;
Cluster& operator=(const Cluster&) = delete;
Cluster(Cluster&&) = default;
Cluster& operator=(Cluster&&) = default;
maxbase::Host host;
SERVER_REF* pBackend;
DCB* pDcb;
bool is_master;
bool is_replying_to_client;
maxsql::PacketTracker tracker;
};
using Clusters = std::vector<Cluster>;
SmartRouterSession(SmartRouter*, MXS_SESSION* pSession, Clusters clusters);
std::vector<maxbase::Host> hosts() const;
// The write functions initialize Cluster flags and Cluster::ProtocolTracker.
bool write_to_host(const maxbase::Host& host, GWBUF* pBuf);
bool write_to_master(GWBUF* pBuf);
bool write_to_all(GWBUF* pBuf);
bool write_split_packets(GWBUF* pBuf);
bool expecting_request_packets() const;
bool expecting_response_packets() const;
bool all_clusters_are_idle() const; // no clusters expect packets
// QueryClassifier::Handler overrides, not used.
bool lock_to_master() override;
bool is_locked_to_master() const override;
bool supports_hint(HINT_TYPE hint_type) const override;
Mode m_mode = Mode::Idle;
GWBUF* m_pDelayed_packet = nullptr;
DCB* m_pClient_dcb;
Clusters m_clusters;
mxs::QueryClassifier m_qc;
};