MXS-2253 Make Cache use the new duration config type

Internally the Cache used seconds, so some changes were needed.
This commit is contained in:
Johan Wikman 2019-02-13 09:43:12 +02:00
parent c116452c25
commit 2528c5fa4d
7 changed files with 82 additions and 73 deletions

View File

@ -5,53 +5,7 @@ This filter was introduced in MariaDB MaxScale 2.1.
Table of Contents
=================
* [Overview](#overview)
* [Limitations](#limitations)
* [Invalidation](#invalidation)
* [Prepared Statements](#prepared-statements)
* [Security](#security)
* [Configuration](#configuration)
* [Filter Parameters](#filter-parameters)
* [storage](#storage)
* [storage_options](#storage_options)
* [hard_ttl](#hard_ttl)
* [soft_ttl](#soft_ttl)
* [max_resultset_rows](#max_resultset_rows)
* [max_resultset_size](#max_resultset_size)
* [max_count](#max_count)
* [max_size](#max_size)
* [rules](#rules)
* [cached_data](#cached_data)
* [selects](#selects)
* [cache_inside_transactions](#cache_inside_transactions)
* [debug](#debug)
* [enabled](#enabled)
* [Runtime Configuration](#runtime-configuration)
* [@maxscale.cache.populate](#maxscalecachepopulate)
* [@maxscale.cache.use](#maxscalecacheuse)
* [@maxscale.cache.soft_ttl](#maxscalecachesoft_ttl)
* [@maxscale.cache.hard_ttl](#maxscalecachehard_ttl)
* [Client Driven Caching](#client-driven-caching)
* [Rules](#rules-1)
* [When to Store](#when-to-store)
* [Qualified Names](#qualified-names)
* [Implication of the <em>default</em> database](#implication-of-the-default-database)
* [Regexp Matching](#regexp-matching)
* [Examples](#examples)
* [When to Use](#when-to-use)
* [Examples](#examples-1)
* [Security](#security-1)
* [Storage](#storage-1)
* [storage_inmemory](#storage_inmemory)
* [storage_rocksdb](#storage_rocksdb)
* [Parameters](#parameters)
* [cache_directory](#cache_directory)
* [collect_statistics](#collect_statistics)
* [Example](#example)
* [Configuration](#configuration-1)
* [cache_rules.json](#cache_rulesjson)
* [Performance](#performance)
* [Summary](#summary)
[TOC]
## Overview
@ -173,14 +127,19 @@ storage_options=storage_specific_option1=value1,storage_specific_option2=value2
#### `hard_ttl`
_Hard time to live_; the maximum amount of time - in seconds - the cached
_Hard time to live_; the maximum amount of time the cached
result is used before it is discarded and the result is fetched from the
backend (and cached). See also `soft_ttl` below.
```
hard_ttl=60
hard_ttl=60s
```
The default value is `0`, which means no limit.
The default value is `0s`, which means no limit.
The duration can be specified as explained
[here](Getting-Started/Configuration-Guide.md#durations).
If no explicit unit has been specified, the value is interpreted as seconds
in MaxScale 2.4. In subsequent versions a value without a unit may be rejected.
#### `soft_ttl`
@ -194,11 +153,16 @@ from the backend. That is, as long as `soft_ttl` but not `hard_ttl` has passed,
even if several clients request the same value at the same time, there will be
just one request to the backend.
```
soft_ttl=60
soft_ttl=60s
```
The default value is `0`, which means no limit. If the value of `soft_ttl` is
larger than `hard_ttl` it will be adjusted down to the same value.
The duration can be specifed as explained
[here](Getting-Started/Configuration-Guide.md#durations).
If no explicit unit has been specified, the value is interpreted as seconds
in MaxScale 2.4. In subsequent versions a value without a unit may be rejected.
#### `max_resultset_rows`
Specifies the maximum number of rows a resultset can have in order to be

View File

@ -209,3 +209,20 @@ json_t* Cache::do_get_info(uint32_t what) const
return pInfo;
}
//static
uint64_t Cache::time_ms()
{
timespec t;
int rv = clock_gettime(CLOCK_MONOTONIC_COARSE, &t);
if (rv != 0)
{
mxb_assert(errno == EINVAL); // CLOCK_MONOTONIC_COARSE not supported.
rv = clock_gettime(CLOCK_MONOTONIC, &t);
mxb_assert(rv == 0);
}
return t.tv_sec * 1000 + (t.tv_nsec / 1000000);
}

View File

@ -56,10 +56,10 @@ typedef enum cache_selects
#define CACHE_ZDEFAULT_MAX_RESULTSET_ROWS "0"
// Bytes
#define CACHE_ZDEFAULT_MAX_RESULTSET_SIZE "0"
// Seconds
#define CACHE_ZDEFAULT_HARD_TTL "0"
// Seconds
#define CACHE_ZDEFAULT_SOFT_TTL "0"
// Duration
#define CACHE_ZDEFAULT_HARD_TTL "0s"
// Duration
#define CACHE_ZDEFAULT_SOFT_TTL "0s"
// Integer value
#define CACHE_ZDEFAULT_DEBUG "0"
// Positive integer
@ -208,6 +208,14 @@ public:
*/
virtual cache_result_t del_value(const CACHE_KEY& key) = 0;
/**
* Returns the monotonic time, expressed in milliseconds, since an
* unspecified starting point.
*
* @return The time.
*/
static uint64_t time_ms();
protected:
Cache(const std::string& name,
const CACHE_CONFIG* pConfig,

View File

@ -191,12 +191,12 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
},
{
"hard_ttl",
MXS_MODULE_PARAM_COUNT,
MXS_MODULE_PARAM_DURATION,
CACHE_ZDEFAULT_HARD_TTL
},
{
"soft_ttl",
MXS_MODULE_PARAM_COUNT,
MXS_MODULE_PARAM_DURATION,
CACHE_ZDEFAULT_SOFT_TTL
},
{
@ -346,8 +346,8 @@ bool CacheFilter::process_params(MXS_CONFIG_PARAMETER* ppParams, CACHE_CONFIG& c
bool error = false;
config.debug = ppParams->get_integer("debug");
config.hard_ttl = ppParams->get_integer("hard_ttl");
config.soft_ttl = ppParams->get_integer("soft_ttl");
config.hard_ttl = ppParams->get_duration("hard_ttl", mxs::config::INTERPRET_AS_SECONDS).count();
config.soft_ttl = ppParams->get_duration("soft_ttl", mxs::config::INTERPRET_AS_SECONDS).count();
config.max_size = ppParams->get_size("max_size");
config.max_count = ppParams->get_integer("max_count");
config.storage = ppParams->get_c_str_copy("storage");

View File

@ -16,6 +16,7 @@
#include <maxscale/alloc.h>
#include <maxscale/modutil.hh>
#include <maxscale/query_classifier.hh>
#include "../../cache.hh"
#include "inmemorystoragest.hh"
#include "inmemorystoragemt.hh"
@ -31,6 +32,7 @@ const size_t INMEMORY_KEY_LENGTH = 2 * SHA512_DIGEST_LENGTH;
#if INMEMORY_KEY_LENGTH > CACHE_KEY_MAXLEN
#error storage_inmemory key is too long.
#endif
}
InMemoryStorage::InMemoryStorage(const string& name, const CACHE_STORAGE_CONFIG& config)
@ -162,7 +164,7 @@ cache_result_t InMemoryStorage::do_get_value(const CACHE_KEY& key,
Entry& entry = i->second;
uint32_t now = time(NULL);
int64_t now = Cache::time_ms();
bool is_hard_stale = hard_ttl == 0 ? false : (now - entry.time > hard_ttl);
bool is_soft_stale = soft_ttl == 0 ? false : (now - entry.time > soft_ttl);
@ -251,7 +253,7 @@ cache_result_t InMemoryStorage::do_put_value(const CACHE_KEY& key, const GWBUF&
const uint8_t* pData = GWBUF_DATA(&value);
copy(pData, pData + size, pEntry->value.begin());
pEntry->time = time(NULL);
pEntry->time = Cache::time_ms();
return CACHE_RESULT_OK;
}

View File

@ -73,8 +73,8 @@ private:
{
}
uint32_t time;
Value value;
int64_t time;
Value value;
};
struct Stats

View File

@ -18,6 +18,24 @@
using namespace std;
namespace
{
unsigned int millisleep(unsigned int milliseconds)
{
unsigned int seconds = milliseconds / 1000;
milliseconds -= (seconds * 1000);
timespec req = { seconds, milliseconds * 1000000 };
timespec rem = { 0, 0 };
nanosleep(&req, &rem);
return rem.tv_sec * 1000 + rem.tv_nsec / 1000000;
}
}
//
// class TesterStorage::HitTask
//
@ -276,8 +294,8 @@ int TesterStorage::test_ttl(const CacheItems& cache_items)
out() << "ST" << endl;
config.thread_model = CACHE_THREAD_MODEL_ST;
config.hard_ttl = 6;
config.soft_ttl = 3;
config.hard_ttl = 6000;
config.soft_ttl = 3000;
Storage* pStorage;
@ -293,8 +311,8 @@ int TesterStorage::test_ttl(const CacheItems& cache_items)
out() << "MT" << endl;
config.thread_model = CACHE_THREAD_MODEL_MT;
config.hard_ttl = 6;
config.soft_ttl = 3;
config.hard_ttl = 6000;
config.soft_ttl = 3000;
int rv2 = EXIT_FAILURE;
pStorage = get_storage(config);
@ -342,8 +360,8 @@ int TesterStorage::test_ttl(const CacheItems& cache_items, Storage& storage)
else
{
// Let's stay just below the soft_ttl value.
sleep(soft_ttl - 1);
slept += soft_ttl - 1;
millisleep(soft_ttl - 1000);
slept += soft_ttl - 1000;
GWBUF* pValue;
@ -359,8 +377,8 @@ int TesterStorage::test_ttl(const CacheItems& cache_items, Storage& storage)
gwbuf_free(pValue);
sleep(2); // Expected to get us passed the soft ttl.
slept += 2;
millisleep(2000); // Expected to get us passed the soft ttl.
slept += 2000;
pValue = NULL;
result = storage.get_value(cache_item.first, 0, &pValue);
@ -385,8 +403,8 @@ int TesterStorage::test_ttl(const CacheItems& cache_items, Storage& storage)
gwbuf_free(pValue);
sleep(hard_ttl - slept + 1); // Expected to get us passed the hard ttl.
slept += hard_ttl - slept + 1;
millisleep(hard_ttl - slept + 1000); // Expected to get us passed the hard ttl.
slept += hard_ttl - slept + 1000;
pValue = NULL;
result = storage.get_value(cache_item.first, CACHE_FLAGS_INCLUDE_STALE, &pValue);