From 65a8e1faa5b2051a7473b0b754faa9453ee79bae Mon Sep 17 00:00:00 2001 From: HowJMay Date: Mon, 9 Mar 2020 13:17:26 +0800 Subject: [PATCH] feat(cache): Check cache database capacity `cache_occupied_space()` would return the used size in caching database. close #488 --- accelerator/cli_info.h | 2 ++ accelerator/config.c | 4 ++++ accelerator/config.h | 4 +++- accelerator/main.c | 5 +++++ tests/unit-test/test_cache.c | 3 +++ utils/cache/backend_redis.c | 37 ++++++++++++++++++++++++++++++++++++ utils/cache/cache.h | 9 +++++++++ 7 files changed, 63 insertions(+), 1 deletion(-) diff --git a/accelerator/cli_info.h b/accelerator/cli_info.h index 6b26ad90..07f31ac1 100644 --- a/accelerator/cli_info.h +++ b/accelerator/cli_info.h @@ -54,6 +54,7 @@ typedef enum ta_cli_arg_value_e { NO_GTTA, BUFFER_LIST, DONE_LIST, + REDIS_CAPACITY, /** LOGGER */ QUIET, @@ -90,6 +91,7 @@ static struct ta_cli_argument_s { {"no-gtta", no_argument, NULL, NO_GTTA, "Disable getTransactionToConfirm (gTTA) when sending transacation"}, {"buffer_list", required_argument, NULL, BUFFER_LIST, "Set the value of `buffer_list_name`"}, {"done_list", required_argument, NULL, DONE_LIST, "Set the value of `done_list_name`"}, + {"redis_capacity", required_argument, NULL, REDIS_CAPACITY, "Set the maximum redis capacity`"}, {"quiet", no_argument, NULL, QUIET, "Disable logger"}, {NULL, 0, NULL, 0, NULL}}; diff --git a/accelerator/config.c b/accelerator/config.c index 77a6621d..b2a3796c 100644 --- a/accelerator/config.c +++ b/accelerator/config.c @@ -175,6 +175,9 @@ status_t cli_core_set(ta_core_t* const core, int key, char* const value) { case DONE_LIST: cache->done_list_name = value; break; + case REDIS_MAX_CAPACITY: + cache->redis_capacity = value; + break; // File configuration case CONF_CLI: { @@ -224,6 +227,7 @@ status_t ta_core_default_init(ta_core_t* const core) { cache->cache_state = false; cache->buffer_list_name = BUFFER_LIST_NAME; cache->done_list_name = DONE_LIST_NAME; + cache->redis_capacity = REDIS_MAX_CAPACITY; ta_log_info("Initializing IRI configuration\n"); iota_conf->milestone_depth = MILESTONE_DEPTH; diff --git a/accelerator/config.h b/accelerator/config.h index 05425b82..c610cce0 100644 --- a/accelerator/config.h +++ b/accelerator/config.h @@ -55,7 +55,8 @@ extern "C" { #define MAM_FILE_PREFIX "/tmp/mam_bin_XXXXXX" #define BUFFER_LIST_NAME "txn_buff_list" #define DONE_LIST_NAME "done_txn_buff_list" -#define IRI_HEALTH_TRACK_PERIOD 1800 // Check every half hour in default +#define REDIS_MAX_CAPACITY 170 * 1024 * 1024 // default in 170MB +#define IRI_HEALTH_TRACK_PERIOD 1800 // Check every half hour in default /** @name Redis connection config */ /** @{ */ @@ -96,6 +97,7 @@ typedef struct ta_cache_s { char* done_list_name; /**< Name of the list to store successfully broadcast transactions from buffer */ uint16_t port; /**< Binding port of redis server */ bool cache_state; /**< Set it true to turn on cache server */ + long int redis_capacity /**< The maximum capacity of redis cache server */ } ta_cache_t; /** struct type of accelerator core */ diff --git a/accelerator/main.c b/accelerator/main.c index b7a02052..79880dbc 100644 --- a/accelerator/main.c +++ b/accelerator/main.c @@ -40,6 +40,11 @@ void health_track(void* arg) { } } + // The usage exceeds the maximum redis capacity + if (core->cache.redis_capacity < cache_occupied_space()) { + // TODO clean redis + } + sleep(core->ta_conf.health_track_period); } } diff --git a/tests/unit-test/test_cache.c b/tests/unit-test/test_cache.c index 2a981e6d..6742f761 100644 --- a/tests/unit-test/test_cache.c +++ b/tests/unit-test/test_cache.c @@ -75,6 +75,8 @@ void test_cache_list_pop(void) { TEST_ASSERT_EQUAL_STRING(TEST_UUID, res); } +void test_cache_occupied_space() { TEST_ASSERT_GREATER_THAN(-1, cache_occupied_space()); } + int main(void) { UNITY_BEGIN(); cache_init(true, REDIS_HOST, REDIS_PORT); @@ -87,6 +89,7 @@ int main(void) { RUN_TEST(test_cache_list_at); RUN_TEST(test_cache_list_size); RUN_TEST(test_cache_list_pop); + RUN_TEST(test_cache_occupied_space); cache_stop(); return UNITY_END(); } diff --git a/utils/cache/backend_redis.c b/utils/cache/backend_redis.c index edfa2a5b..e37d9f89 100644 --- a/utils/cache/backend_redis.c +++ b/utils/cache/backend_redis.c @@ -6,7 +6,9 @@ * "LICENSE" at the root of this distribution. */ +#include #include +#include #include "cache.h" #include "common/logger.h" @@ -227,6 +229,32 @@ static status_t redis_list_pop(redisContext* c, const char* const key, char* res return ret; } +long int redis_occupied_space(redisContext* c) { + const char size_field[] = "used_memory:"; + redisReply* reply = redisCommand(c, "INFO"); + if (reply->type == REDIS_REPLY_STRING) { + // Parsing the result returned by redis. Get informationa from field `used_memory` + char* str = strstr(reply->str, size_field); + char* size_str = strtok(str, "\n"); + char* ptr = size_str + strlen(size_field); + + char* strtol_p = NULL; + long int strtol_temp; + strtol_temp = strtol(ptr, &strtol_p, 10); + if (strtol_p != ptr && errno != ERANGE && strtol_temp >= INT_MIN && strtol_temp <= INT_MAX) { + freeReplyObject(reply); + return strtol_temp; + } else { + ta_log_error("Malformed input or illegal input character\n"); + } + } else { + ta_log_error("%s\n", "Failed to operate redis command."); + } + + freeReplyObject(reply); + return -1; +} + /* * Public functions */ @@ -328,3 +356,12 @@ status_t cache_list_pop(const char* const key, char* res) { } return redis_list_pop(CONN(cache)->rc, key, res); } + +long int cache_occupied_space() { + if (!cache_state) { + ta_log_info("%s\n", "SC_CACHE_OFF"); + return SC_CACHE_OFF; + } + + return redis_occupied_space(CONN(cache)->rc); +} diff --git a/utils/cache/cache.h b/utils/cache/cache.h index cf19e110..6622a1f7 100644 --- a/utils/cache/cache.h +++ b/utils/cache/cache.h @@ -187,6 +187,15 @@ status_t cache_list_exist(const char* const key, const char* const value, const */ status_t cache_list_pop(const char* const key, char* res); +/** + * Get the size of redis occupied space. + * + * @return + * - Used size of the cache database on success + * - `-1` on error + */ +long int cache_occupied_space(); + #ifdef __cplusplus } #endif