From 79a03049a10f0687fa17a86aeb9f57eea65911a3 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 22 Nov 2016 10:57:23 +0200 Subject: [PATCH] Enable fetching of stale items It is now possible to specify that a cache item should be returned if it exists, even if it is stale. --- server/modules/filter/cache/cache.c | 2 +- server/modules/filter/cache/cache_storage_api.h | 11 +++++++++++ .../storage/storage_rocksdb/rocksdbstorage.cc | 15 ++++++++++++--- .../storage/storage_rocksdb/rocksdbstorage.h | 2 +- .../storage/storage_rocksdb/storage_rocksdb.cc | 7 +++++-- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/server/modules/filter/cache/cache.c b/server/modules/filter/cache/cache.c index 302b40a5e..c633d6661 100644 --- a/server/modules/filter/cache/cache.c +++ b/server/modules/filter/cache/cache.c @@ -1087,7 +1087,7 @@ static bool route_using_cache(CACHE_SESSION_DATA *csdata, if (result == CACHE_RESULT_OK) { - result = csdata->api->getValue(csdata->storage, csdata->key, value); + result = csdata->api->getValue(csdata->storage, csdata->key, CACHE_FLAGS_NONE, value); } else { diff --git a/server/modules/filter/cache/cache_storage_api.h b/server/modules/filter/cache/cache_storage_api.h index a413afe54..a68aecd93 100644 --- a/server/modules/filter/cache/cache_storage_api.h +++ b/server/modules/filter/cache/cache_storage_api.h @@ -26,10 +26,17 @@ typedef enum cache_result { CACHE_RESULT_OK, CACHE_RESULT_NOT_FOUND, + CACHE_RESULT_STALE, CACHE_RESULT_OUT_OF_RESOURCES, CACHE_RESULT_ERROR } cache_result_t; +typedef enum cache_flags +{ + CACHE_FLAGS_NONE = 0x00, + CACHE_FLAGS_INCLUDE_STALE = 0x01, +} cache_flags_t; + typedef void* CACHE_STORAGE; enum @@ -88,14 +95,18 @@ typedef struct cache_storage_api * * @param storage Pointer to a CACHE_STORAGE. * @param key A key generated with getKey. + * @param flags Mask of cache_flags_t values. * @param result Pointer to variable that after a successful return will * point to a GWBUF. * @return CACHE_RESULT_OK if item was found, + * CACHE_RESULT_STALE if CACHE_FLAGS_INCLUDE_STALE was specified in + * flags and the item was found but stale, * CACHE_RESULT_NOT_FOUND if item was not found (which may be because * the ttl was reached), or some other error code. */ cache_result_t (*getValue)(CACHE_STORAGE* storage, const char* key, + uint32_t flags, GWBUF** result); /** diff --git a/server/modules/filter/cache/storage/storage_rocksdb/rocksdbstorage.cc b/server/modules/filter/cache/storage/storage_rocksdb/rocksdbstorage.cc index 966bfdf8b..75a8005ff 100644 --- a/server/modules/filter/cache/storage/storage_rocksdb/rocksdbstorage.cc +++ b/server/modules/filter/cache/storage/storage_rocksdb/rocksdbstorage.cc @@ -403,7 +403,7 @@ cache_result_t RocksDBStorage::getKey(const char* zDefaultDB, const GWBUF* pQuer return CACHE_RESULT_OK; } -cache_result_t RocksDBStorage::getValue(const char* pKey, GWBUF** ppResult) +cache_result_t RocksDBStorage::getValue(const char* pKey, uint32_t flags, GWBUF** ppResult) { // Use the root DB so that we get the value *with* the timestamp at the end. rocksdb::DB* pDb = m_sDb->GetRootDB(); @@ -419,7 +419,9 @@ cache_result_t RocksDBStorage::getValue(const char* pKey, GWBUF** ppResult) case rocksdb::Status::kOk: if (value.length() >= RocksDBInternals::TS_LENGTH) { - if (!RocksDBInternals::IsStale(value, m_ttl, rocksdb::Env::Default())) + bool isStale = RocksDBInternals::IsStale(value, m_ttl, rocksdb::Env::Default()); + + if (!isStale || ((flags & CACHE_FLAGS_INCLUDE_STALE) != 0)) { size_t length = value.length() - RocksDBInternals::TS_LENGTH; @@ -429,7 +431,14 @@ cache_result_t RocksDBStorage::getValue(const char* pKey, GWBUF** ppResult) { memcpy(GWBUF_DATA(*ppResult), value.data(), length); - result = CACHE_RESULT_OK; + if (isStale) + { + result = CACHE_RESULT_STALE; + } + else + { + result = CACHE_RESULT_OK; + } } } else diff --git a/server/modules/filter/cache/storage/storage_rocksdb/rocksdbstorage.h b/server/modules/filter/cache/storage/storage_rocksdb/rocksdbstorage.h index a3bf85ba7..1a3187517 100644 --- a/server/modules/filter/cache/storage/storage_rocksdb/rocksdbstorage.h +++ b/server/modules/filter/cache/storage/storage_rocksdb/rocksdbstorage.h @@ -30,7 +30,7 @@ public: ~RocksDBStorage(); cache_result_t getKey(const char* zDefaultDB, const GWBUF* pQuery, char* pKey); - cache_result_t getValue(const char* pKey, GWBUF** ppResult); + cache_result_t getValue(const char* pKey, uint32_t flags, GWBUF** ppResult); cache_result_t putValue(const char* pKey, const GWBUF* pValue); private: diff --git a/server/modules/filter/cache/storage/storage_rocksdb/storage_rocksdb.cc b/server/modules/filter/cache/storage/storage_rocksdb/storage_rocksdb.cc index d5e72aabd..b21037129 100644 --- a/server/modules/filter/cache/storage/storage_rocksdb/storage_rocksdb.cc +++ b/server/modules/filter/cache/storage/storage_rocksdb/storage_rocksdb.cc @@ -86,7 +86,10 @@ cache_result_t getKey(CACHE_STORAGE* pStorage, return result; } -cache_result_t getValue(CACHE_STORAGE* pStorage, const char* pKey, GWBUF** ppResult) +cache_result_t getValue(CACHE_STORAGE* pStorage, + const char* pKey, + uint32_t flags, + GWBUF** ppResult) { ss_dassert(pStorage); ss_dassert(pKey); @@ -96,7 +99,7 @@ cache_result_t getValue(CACHE_STORAGE* pStorage, const char* pKey, GWBUF** ppRes try { - result = reinterpret_cast(pStorage)->getValue(pKey, ppResult); + result = reinterpret_cast(pStorage)->getValue(pKey, flags, ppResult); } catch (const std::bad_alloc&) {