Cache: Derive CacheFilter class from maxscale::CacheFilter

Now everything needed for cleanly transfer the control between the
C filter API of MaxScale and a C++ filter implementation is handled
automatically. Nothing of the earlier boiler-plate code is needed.
This commit is contained in:
Johan Wikman 2016-12-09 00:07:06 +02:00
parent c421026ce9
commit 3877d7bc5e
3 changed files with 96 additions and 263 deletions

View File

@ -12,25 +12,22 @@
*/
#define MXS_MODULE_NAME "cache"
#include "cachefilter.h"
#include <exception>
#include <new>
#include "cachefilter.hh"
#include <maxscale/alloc.h>
#include <maxscale/filter.h>
#include <maxscale/gwdirs.h>
#include <maxscale/modulecmd.h>
#include <maxscale/cpp.hh>
#include "cachemt.h"
#include "cachept.h"
#include "cachefiltersession.hh"
using std::auto_ptr;
using std::string;
static char VERSION_STRING[] = "V1.0.0";
namespace
{
static char VERSION_STRING[] = "V1.0.0";
static const CACHE_CONFIG DEFAULT_CONFIG =
{
CACHE_DEFAULT_MAX_RESULTSET_ROWS,
@ -47,7 +44,6 @@ static const CACHE_CONFIG DEFAULT_CONFIG =
CACHE_DEFAULT_THREAD_MODEL,
};
/**
* Frees all data of a config object, but not the object itself
*
@ -95,45 +91,14 @@ void cache_config_reset(CACHE_CONFIG& config)
memset(&config, 0, sizeof(config));
}
}
typedef struct cache_filter
{
cache_filter()
: config(DEFAULT_CONFIG)
, pCache(NULL)
{
}
~cache_filter()
{
delete pCache;
cache_config_finish(config);
}
CACHE_CONFIG config;
Cache* pCache;
private:
cache_filter(const cache_filter&);
cache_filter& operator = (const cache_filter&);
} CACHE_FILTER;
static FILTER* createInstance(const char* zName, char** pzOptions, FILTER_PARAMETER** ppParams);
static void* newSession(FILTER* pInstance, SESSION* pSession);
static void closeSession(FILTER* pInstance, void* pSessionData);
static void freeSession(FILTER* pInstance, void* pSessionData);
static void setDownstream(FILTER* pInstance, void* pSessionData, DOWNSTREAM* pDownstream);
static void setUpstream(FILTER* pInstance, void* pSessionData, UPSTREAM* pUpstream);
static int routeQuery(FILTER* pInstance, void* pSessionData, GWBUF* pPacket);
static int clientReply(FILTER* pInstance, void* pSessionData, GWBUF* pPacket);
static void diagnostics(FILTER* pInstance, void* pSessionData, DCB* pDcb);
static uint64_t getCapabilities(void);
static void destroyInstance(FILTER* pInstance);
static bool process_params(char **pzOptions, FILTER_PARAMETER **ppParams, CACHE_CONFIG& config);
static bool cache_command_show(const MODULECMD_ARG* pArgs)
/**
* Implement "call command cache show ..."
*
* @param pArgs The arguments of the command.
*
* @return True, if the command was handled.
*/
bool cache_command_show(const MODULECMD_ARG* pArgs)
{
ss_dassert(pArgs->argc == 2);
ss_dassert(MODULECMD_GET_TYPE(&pArgs->argv[0].type) == MODULECMD_ARG_OUTPUT);
@ -147,9 +112,9 @@ static bool cache_command_show(const MODULECMD_ARG* pArgs)
if (strcmp(pFilterDef->module, "cache") == 0)
{
CACHE_FILTER* pFilter = reinterpret_cast<CACHE_FILTER*>(pFilterDef->filter);
CacheFilter* pFilter = reinterpret_cast<CacheFilter*>(pFilterDef->filter);
pFilter->pCache->show(pDcb);
pFilter->cache().show(pDcb);
}
else
{
@ -159,6 +124,8 @@ static bool cache_command_show(const MODULECMD_ARG* pArgs)
return true;
}
}
//
// Global symbols of the Module
//
@ -176,10 +143,6 @@ extern "C" char *version()
return VERSION_STRING;
}
/**
* The module initialization functions, called when the module has
* been loaded.
*/
extern "C" void ModuleInit()
{
static modulecmd_arg_type_t show_argv[] =
@ -194,63 +157,46 @@ extern "C" void ModuleInit()
MXS_NOTICE("Initialized cache module %s.\n", VERSION_STRING);
}
/**
* The module entry point function, called when the module is loaded.
*
* @return The module object.
*/
extern "C" FILTER_OBJECT *GetModuleObject()
{
static FILTER_OBJECT object =
{
createInstance,
newSession,
closeSession,
freeSession,
setDownstream,
setUpstream,
routeQuery,
clientReply,
diagnostics,
getCapabilities,
destroyInstance,
};
return &object;
return &CacheFilter::s_object;
};
//
// API Implementation BEGIN
// CacheFilter
//
/**
* Create an instance of the cache filter for a particular service
* within MaxScale.
*
* @param zName The name of the instance (as defined in the config file).
* @param pzOptions The options for this filter
* @param ppparams The array of name/value pair parameters for the filter
*
* @return The instance data for this new instance
*/
static FILTER *createInstance(const char* zName, char** pzOptions, FILTER_PARAMETER** ppParams)
CacheFilter::CacheFilter()
: m_config(DEFAULT_CONFIG)
{
CACHE_FILTER* pFilter = new (std::nothrow) CACHE_FILTER;
}
CacheFilter::~CacheFilter()
{
cache_config_finish(m_config);
}
// static
CacheFilter* CacheFilter::create(const char* zName, char** pzOptions, FILTER_PARAMETER** ppParams)
{
CacheFilter* pFilter = new CacheFilter;
if (pFilter)
{
if (process_params(pzOptions, ppParams, pFilter->config))
Cache* pCache = NULL;
if (process_params(pzOptions, ppParams, pFilter->m_config))
{
switch (pFilter->config.thread_model)
switch (pFilter->m_config.thread_model)
{
case CACHE_THREAD_MODEL_MT:
MXS_NOTICE("Creating shared cache.");
MXS_EXCEPTION_GUARD(pFilter->pCache = CacheMT::Create(zName, &pFilter->config));
MXS_EXCEPTION_GUARD(pCache = CacheMT::Create(zName, &pFilter->m_config));
break;
case CACHE_THREAD_MODEL_ST:
MXS_NOTICE("Creating thread specific cache.");
MXS_EXCEPTION_GUARD(pFilter->pCache = CachePT::Create(zName, &pFilter->config));
MXS_EXCEPTION_GUARD(pCache = CachePT::Create(zName, &pFilter->m_config));
break;
default:
@ -258,182 +204,34 @@ static FILTER *createInstance(const char* zName, char** pzOptions, FILTER_PARAME
}
}
if (!pFilter->pCache)
if (pCache)
{
cache_config_finish(pFilter->config);
pFilter->m_sCache = auto_ptr<Cache>(pCache);
}
else
{
cache_config_finish(pFilter->m_config);
delete pFilter;
pFilter = NULL;
}
}
return reinterpret_cast<FILTER*>(pFilter);
return pFilter;
}
/**
* Associate a new session with this instance of the filter.
*
* @param pInstance The cache instance data
* @param pSession The session itself
*
* @return Session specific data for this session
*/
static void *newSession(FILTER* pInstance, SESSION* pSession)
CacheFilterSession* CacheFilter::newSession(SESSION* pSession)
{
CACHE_FILTER *pFilter = reinterpret_cast<CACHE_FILTER*>(pInstance);
Cache* pCache = pFilter->pCache;
CacheFilterSession* pCacheFilterSession = NULL;
MXS_EXCEPTION_GUARD(pCacheFilterSession = CacheFilterSession::Create(pCache, pSession));
return pCacheFilterSession;
return CacheFilterSession::Create(m_sCache.get(), pSession);
}
/**
* A session has been closed.
*
* @param pInstance The cache instance data
* @param pSessionData The session data of the session being closed
*/
static void closeSession(FILTER* pInstance, void* pSessionData)
{
CacheFilterSession* pCacheFilterSession = static_cast<CacheFilterSession*>(pSessionData);
MXS_EXCEPTION_GUARD(pCacheFilterSession->close());
}
/**
* Free the session data.
*
* @param pInstance The cache instance data
* @param pSessionData The session data of the session being closed
*/
static void freeSession(FILTER* pInstance, void* pSessionData)
{
CacheFilterSession* pCacheFilterSession = static_cast<CacheFilterSession*>(pSessionData);
delete pCacheFilterSession;
}
/**
* Set the downstream component for this filter.
*
* @param pInstance The cache instance data
* @param pSessionData The session data of the session
* @param pDownstream The downstream filter or router
*/
static void setDownstream(FILTER* pInstance, void* pSessionData, DOWNSTREAM* pDownstream)
{
CacheFilterSession* pCacheFilterSession = static_cast<CacheFilterSession*>(pSessionData);
CacheFilterSession::Downstream down(*pDownstream);
MXS_EXCEPTION_GUARD(pCacheFilterSession->setDownstream(down));
}
/**
* Set the upstream component for this filter.
*
* @param pInstance The cache instance data
* @param pSessionData The session data of the session
* @param pUpstream The upstream filter or router
*/
static void setUpstream(FILTER* pInstance, void* pSessionData, UPSTREAM* pUpstream)
{
CacheFilterSession* pCacheFilterSession = static_cast<CacheFilterSession*>(pSessionData);
CacheFilterSession::Upstream up(*pUpstream);
MXS_EXCEPTION_GUARD(pCacheFilterSession->setUpstream(up));
}
/**
* A request on its way to a backend is delivered to this function.
*
* @param pInstance The filter instance data
* @param pSessionData The filter session data
* @param pPacket Buffer containing an MySQL protocol packet.
*/
static int routeQuery(FILTER* pInstance, void* pSessionData, GWBUF* pPacket)
{
CacheFilterSession* pCacheFilterSession = static_cast<CacheFilterSession*>(pSessionData);
int rv = 0;
MXS_EXCEPTION_GUARD(rv = pCacheFilterSession->routeQuery(pPacket));
return rv;
}
/**
* A response on its way to the client is delivered to this function.
*
* @param pInstance The filter instance data
* @param pSessionData The filter session data
* @param pPacket The response data
*/
static int clientReply(FILTER* pInstance, void* pSessionData, GWBUF* pPacket)
{
CacheFilterSession* pCacheFilterSession = static_cast<CacheFilterSession*>(pSessionData);
int rv = 0;
MXS_EXCEPTION_GUARD(rv = pCacheFilterSession->clientReply(pPacket));
return rv;
}
/**
* Diagnostics routine
*
* If cpSessionData is NULL then print diagnostics on the instance as a whole,
* otherwise print diagnostics for the particular session.
*
* @param pInstance The filter instance
* @param pSessionData Filter session, may be NULL
* @param pDcb The DCB for diagnostic output
*/
static void diagnostics(FILTER* pInstance, void* pSessionData, DCB* pDcb)
{
CacheFilterSession* pCacheFilterSession = static_cast<CacheFilterSession*>(pSessionData);
MXS_EXCEPTION_GUARD(pCacheFilterSession->diagnostics(pDcb));
}
/**
* Capability routine.
*
* @return The capabilities of the filter.
*/
static uint64_t getCapabilities(void)
// static
uint64_t CacheFilter::getCapabilities()
{
return RCAP_TYPE_TRANSACTION_TRACKING;
}
/**
* Destroy the filter instance.
*
* @param pInstance The filter instance.
*/
static void destroyInstance(FILTER* pInstance)
{
MXS_NOTICE("Deleting Cache filter instance.");
CACHE_FILTER* pFilter = reinterpret_cast<CACHE_FILTER*>(pInstance);
delete pFilter;
}
//
// API Implementation END
//
/**
* Processes the cache params
*
* @param options Options as passed to the filter.
* @param params Parameters as passed to the filter.
* @param config Reference to config instance where params will be stored.
*
* @return True if all parameters could be processed, false otherwise.
*/
static bool process_params(char **pzOptions, FILTER_PARAMETER **ppParams, CACHE_CONFIG& config)
// static
bool CacheFilter::process_params(char **pzOptions, FILTER_PARAMETER **ppParams, CACHE_CONFIG& config)
{
bool error = false;

View File

@ -1,6 +1,4 @@
#pragma once
#ifndef _MAXSCALE_FILTER_CACHE_CACHE_H
#define _MAXSCALE_FILTER_CACHE_CACHE_H
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
@ -16,15 +14,9 @@
#include <maxscale/cdefs.h>
#include <limits.h>
#include <exception>
#include <tr1/functional>
#include <maxscale/hashtable.h>
#include <maxscale/spinlock.h>
#include "rules.h"
#include "cache_storage_api.h"
#include "rules.h"
class Storage;
class StorageFactory;
#define CACHE_DEBUG_NONE 0 /* 0b00000 */
#define CACHE_DEBUG_MATCHING 1 /* 0b00001 */
@ -76,5 +68,3 @@ typedef struct cache_config
uint32_t debug; /**< Debug settings. */
cache_thread_model_t thread_model; /**< Thread model. */
} CACHE_CONFIG;
#endif

View File

@ -0,0 +1,45 @@
#pragma once
/*
* Copyright (c) 2016 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/bsl.
*
* Change Date: 2019-07-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.
*/
#include <maxscale/cdefs.h>
#include <maxscale/filter.hh>
#include "cachefilter.h"
#include "cachefiltersession.hh"
class CacheFilter : public maxscale::Filter<CacheFilter, CacheFilterSession>
{
public:
~CacheFilter();
static CacheFilter* create(const char* zName, char** pzOptions, FILTER_PARAMETER** ppParams);
Cache& cache() { ss_dassert(m_sCache.get()); return *m_sCache.get(); }
const Cache& cache() const { ss_dassert(m_sCache.get()); return *m_sCache.get(); }
CacheFilterSession* newSession(SESSION* pSession);
static uint64_t getCapabilities();
private:
CacheFilter();
CacheFilter(const CacheFilter&);
CacheFilter& operator = (const CacheFilter&);
static bool process_params(char **pzOptions, FILTER_PARAMETER **ppParams, CACHE_CONFIG& config);
private:
CACHE_CONFIG m_config;
std::auto_ptr<Cache> m_sCache;
};