Add show command to cache filter

Initial POC implementation that is capable of outputting the
rules of the cache.

In order to do that conveniently, the json object is retained for
the lifetime of the CACHE_RULES object.
This commit is contained in:
Johan Wikman
2016-12-02 15:09:11 +02:00
parent d9ced5bbab
commit 8f2170c455
6 changed files with 127 additions and 19 deletions

View File

@ -74,6 +74,13 @@ bool Cache::Create(const CACHE_CONFIG& config,
return pFactory != NULL; return pFactory != NULL;
} }
void Cache::show(DCB* pDcb) const
{
dcb_printf(pDcb, "Rules:\n");
size_t indent = 2;
m_sRules->print(pDcb, indent);
}
bool Cache::should_store(const char* zDefaultDb, const GWBUF* pQuery) bool Cache::should_store(const char* zDefaultDb, const GWBUF* pQuery)
{ {
return m_sRules->should_store(zDefaultDb, pQuery); return m_sRules->should_store(zDefaultDb, pQuery);

View File

@ -31,6 +31,8 @@ public:
virtual ~Cache(); virtual ~Cache();
void show(DCB* pDcb) const;
const CACHE_CONFIG& config() const { return m_config; } const CACHE_CONFIG& config() const { return m_config; }
/** /**

View File

@ -18,6 +18,7 @@
#include <maxscale/alloc.h> #include <maxscale/alloc.h>
#include <maxscale/filter.h> #include <maxscale/filter.h>
#include <maxscale/gwdirs.h> #include <maxscale/gwdirs.h>
#include <maxscale/modulecmd.h>
#include "cachemt.h" #include "cachemt.h"
#include "cachept.h" #include "cachept.h"
#include "sessioncache.h" #include "sessioncache.h"
@ -78,6 +79,32 @@ static void destroyInstance(FILTER* pInstance);
static bool process_params(char **pzOptions, FILTER_PARAMETER **ppParams, CACHE_CONFIG& config); static bool process_params(char **pzOptions, FILTER_PARAMETER **ppParams, CACHE_CONFIG& config);
static 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);
ss_dassert(MODULECMD_GET_TYPE(&pArgs->argv[1].type) == MODULECMD_ARG_FILTER);
DCB* pDcb = pArgs->argv[0].value.dcb;
ss_dassert(pDcb);
const FILTER_DEF* pFilterDef = pArgs->argv[1].value.filter;
ss_dassert(pFilterDef);
if (strcmp(pFilterDef->module, "cache") == 0)
{
CACHE_FILTER* pFilter = reinterpret_cast<CACHE_FILTER*>(pFilterDef->filter);
pFilter->pCache->show(pDcb);
}
else
{
dcb_printf(pDcb, "Filter %s exists, but it is not a cache.", pFilterDef->name);
}
return true;
}
// //
// Global symbols of the Module // Global symbols of the Module
// //
@ -101,6 +128,16 @@ extern "C" char *version()
*/ */
extern "C" void ModuleInit() extern "C" void ModuleInit()
{ {
static modulecmd_arg_type_t show_argv[] =
{
{ MODULECMD_ARG_OUTPUT, "The output dcb" },
{ MODULECMD_ARG_FILTER, "Cache name" }
};
modulecmd_register_command("cache", "show", cache_command_show,
MXS_ARRAY_NELEMS(show_argv), show_argv);
MXS_NOTICE("Initialized cache module %s.\n", VERSION_STRING);
} }
/** /**

View File

@ -229,7 +229,11 @@ CACHE_RULES *cache_rules_load(const char *path, uint32_t debug)
if (root) if (root)
{ {
rules = cache_rules_create_from_json(root, debug); rules = cache_rules_create_from_json(root, debug);
json_decref(root);
if (!rules)
{
json_decref(root);
}
} }
else else
{ {
@ -260,7 +264,11 @@ CACHE_RULES *cache_rules_parse(const char *json, uint32_t debug)
if (root) if (root)
{ {
rules = cache_rules_create_from_json(root, debug); rules = cache_rules_create_from_json(root, debug);
json_decref(root);
if (!rules)
{
json_decref(root);
}
} }
else else
{ {
@ -275,12 +283,36 @@ void cache_rules_free(CACHE_RULES *rules)
{ {
if (rules) if (rules)
{ {
if (rules->root)
{
json_decref(rules->root);
}
cache_rule_free(rules->store_rules); cache_rule_free(rules->store_rules);
cache_rule_free(rules->use_rules); cache_rule_free(rules->use_rules);
MXS_FREE(rules); MXS_FREE(rules);
} }
} }
void cache_rules_print(const CACHE_RULES *self, DCB *dcb, size_t indent)
{
if (self->root)
{
size_t flags = JSON_PRESERVE_ORDER;
char *s = json_dumps(self->root, JSON_PRESERVE_ORDER | JSON_INDENT(indent));
if (s)
{
dcb_printf(dcb, "%s\n", s);
free(s);
}
}
else
{
dcb_printf(dcb, "{\n}\n");
}
}
bool cache_rules_should_store(CACHE_RULES *self, const char *default_db, const GWBUF* query) bool cache_rules_should_store(CACHE_RULES *self, const char *default_db, const GWBUF* query)
{ {
bool should_store = false; bool should_store = false;
@ -381,6 +413,11 @@ CacheRules* CacheRules::load(const char *zpath, uint32_t debug)
return pthis; return pthis;
} }
void CacheRules::print(DCB* pdcb, size_t indent) const
{
cache_rules_print(prules_, pdcb, indent);
}
bool CacheRules::should_store(const char* zdefault_db, const GWBUF* pquery) const bool CacheRules::should_store(const char* zdefault_db, const GWBUF* pquery) const
{ {
return cache_rules_should_store(prules_, zdefault_db, pquery); return cache_rules_should_store(prules_, zdefault_db, pquery);
@ -1807,7 +1844,11 @@ static CACHE_RULES* cache_rules_create_from_json(json_t* root, uint32_t debug)
if (rules) if (rules)
{ {
if (!cache_rules_parse_json(rules, root)) if (cache_rules_parse_json(rules, root))
{
rules->root = root;
}
else
{ {
cache_rules_free(rules); cache_rules_free(rules);
rules = NULL; rules = NULL;

View File

@ -63,6 +63,7 @@ typedef struct cache_rule
typedef struct cache_rules typedef struct cache_rules
{ {
json_t *root; // The JSON root object.
uint32_t debug; // The debug level. uint32_t debug; // The debug level.
CACHE_RULE *store_rules; // The rules for when to store data to the cache. CACHE_RULE *store_rules; // The rules for when to store data to the cache.
CACHE_RULE *use_rules; // The rules for when to use data from the cache. CACHE_RULE *use_rules; // The rules for when to use data from the cache.
@ -124,6 +125,14 @@ CACHE_RULES *cache_rules_load(const char *path, uint32_t debug);
*/ */
CACHE_RULES *cache_rules_parse(const char *json, uint32_t debug); CACHE_RULES *cache_rules_parse(const char *json, uint32_t debug);
/**
* Prints the rules.
*
* @param pdcb The DCB where the rules should be printed.
* @param indent By how many spaces to indent the output.
*/
void cache_rules_print(const CACHE_RULES *rules, DCB* dcb, size_t indent);
/** /**
* Returns boolean indicating whether the result of the query should be stored. * Returns boolean indicating whether the result of the query should be stored.
* *
@ -173,23 +182,31 @@ public:
*/ */
static CacheRules* load(const char *zpath, uint32_t debug); static CacheRules* load(const char *zpath, uint32_t debug);
/** /**
* Returns boolean indicating whether the result of the query should be stored. * Prints the rules.
* *
* @param zdefault_db The current default database, NULL if there is none. * @param pdcb DCB where the rules should be printed.
* @param pquery The query, expected to contain a COM_QUERY. * @param indent By how many spaces to indent the output.
* */
* @return True, if the results should be stored. void print(DCB* pdcb, size_t indent) const;
*/
/**
* Returns boolean indicating whether the result of the query should be stored.
*
* @param zdefault_db The current default database, NULL if there is none.
* @param pquery The query, expected to contain a COM_QUERY.
*
* @return True, if the results should be stored.
*/
bool should_store(const char* zdefault_db, const GWBUF* pquery) const; bool should_store(const char* zdefault_db, const GWBUF* pquery) const;
/** /**
* Returns boolean indicating whether the cache should be used, that is consulted. * Returns boolean indicating whether the cache should be used, that is consulted.
* *
* @param psession The current session. * @param psession The current session.
* *
* @return True, if the cache should be used. * @return True, if the cache should be used.
*/ */
bool should_use(const SESSION* psession) const; bool should_use(const SESSION* psession) const;
private: private:

View File

@ -305,7 +305,11 @@ int SessionCache::clientReply(GWBUF* pData)
void SessionCache::diagnostics(DCB* pDcb) void SessionCache::diagnostics(DCB* pDcb)
{ {
dcb_printf(pDcb, "Hello World from Cache!\n"); // Not printing anything. Session of the same instance share the same cache, in
// which case the same information would be printed once per session, or all
// threads (but not sessions) share the same cache, in which case the output
// would be nonsensical.
dcb_printf(pDcb, "\n");
} }
/** /**