diff --git a/src/evict.c b/src/evict.c index 6d27c1380348..754f918b29a8 100644 --- a/src/evict.c +++ b/src/evict.c @@ -682,6 +682,7 @@ int performEvictions(void) { * * AOF and Output buffer memory will be freed eventually so * we only care about memory used by the key space. */ + enterExecutionUnit(1, 0); delta = (long long) zmalloc_used_memory(); latencyStartMonitor(eviction_latency); dbGenericDelete(db,keyobj,server.lazyfree_lazy_eviction,DB_FLAG_KEY_EVICTED); @@ -694,6 +695,7 @@ int performEvictions(void) { notifyKeyspaceEvent(NOTIFY_EVICTED, "evicted", keyobj, db->id); propagateDeletion(db,keyobj,server.lazyfree_lazy_eviction); + exitExecutionUnit(); postExecutionUnitOperations(); decrRefCount(keyobj); keys_freed++; diff --git a/src/expire.c b/src/expire.c index 3a51f8c0d0fc..d787d769cf1e 100644 --- a/src/expire.c +++ b/src/expire.c @@ -54,10 +54,12 @@ int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) { long long t = dictGetSignedIntegerVal(de); if (now > t) { + enterExecutionUnit(1, 0); sds key = dictGetKey(de); robj *keyobj = createStringObject(key,sdslen(key)); deleteExpiredKeyAndPropagate(db,keyobj); decrRefCount(keyobj); + exitExecutionUnit(); return 1; } else { return 0; diff --git a/tests/modules/postnotifications.c b/tests/modules/postnotifications.c index ca3a15b43775..6c2b1eb096b9 100644 --- a/tests/modules/postnotifications.c +++ b/tests/modules/postnotifications.c @@ -90,6 +90,10 @@ static int KeySpace_NotificationEvicted(RedisModuleCtx *ctx, int type, const cha return REDISMODULE_OK; /* do not count the evicted key */ } + if (strncmp(key_str, "before_evicted", 14) == 0) { + return REDISMODULE_OK; /* do not count the before_evicted key */ + } + RedisModuleString *new_key = RedisModule_CreateString(NULL, "evicted", 7); RedisModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, new_key, KeySpace_PostNotificationStringFreePD); return REDISMODULE_OK; @@ -186,6 +190,32 @@ static int KeySpace_PostNotificationsAsyncSet(RedisModuleCtx *ctx, RedisModuleSt return REDISMODULE_OK; } +static void KeySpace_ServerEventCallback(RedisModuleCtx *ctx, RedisModuleEvent eid, uint64_t subevent, void *data) { + REDISMODULE_NOT_USED(eid); + REDISMODULE_NOT_USED(data); + if (subevent > 3) { + RedisModule_Log(ctx, "warning", "Got an unexpected subevent '%ld'", subevent); + return; + } + static const char* events[] = { + "before_deleted", + "before_expired", + "before_evicted", + "before_overwritten", + }; + + const RedisModuleString *key_name = RedisModule_GetKeyNameFromModuleKey(((RedisModuleKeyInfo*)data)->key); + const char *key_str = RedisModule_StringPtrLen(key_name, NULL); + const char *event = events[subevent]; + size_t event_len = strlen(event); + if (strncmp(key_str, event , event_len) == 0) { + return; /* avoid loops */ + } + + RedisModuleString *new_key = RedisModule_CreateString(NULL, event, event_len); + RedisModule_AddPostNotificationJob(ctx, KeySpace_PostNotificationString, new_key, KeySpace_PostNotificationStringFreePD); +} + /* This function must be present on each Redis module. It is used in order to * register the commands into the Redis server. */ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { @@ -222,6 +252,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) return REDISMODULE_ERR; } + if(RedisModule_SubscribeToServerEvent(ctx, RedisModuleEvent_Key, KeySpace_ServerEventCallback) != REDISMODULE_OK){ + return REDISMODULE_ERR; + } + if (RedisModule_CreateCommand(ctx, "postnotification.async_set", KeySpace_PostNotificationsAsyncSet, "write", 0, 0, 0) == REDISMODULE_ERR){ return REDISMODULE_ERR; diff --git a/tests/unit/moduleapi/async_rm_call.tcl b/tests/unit/moduleapi/async_rm_call.tcl index 4799ea124e99..e6209761517e 100644 --- a/tests/unit/moduleapi/async_rm_call.tcl +++ b/tests/unit/moduleapi/async_rm_call.tcl @@ -321,6 +321,7 @@ start_server {tags {"modules"}} { {lpop l} {set string_foo 1} {set string_bar 2} + {incr before_deleted} {incr string_changed{string_foo}} {incr string_changed{string_bar}} {incr string_total} @@ -362,6 +363,7 @@ start_server {tags {"modules"}} { {lpop l} {set string_foo 1} {set string_bar 2} + {incr before_deleted} {incr string_changed{string_foo}} {incr string_changed{string_bar}} {incr string_total} @@ -374,8 +376,11 @@ start_server {tags {"modules"}} { {del string_foo} {set string_foo 1} {set string_bar 2} + {incr before_deleted} + {incr before_expired} {incr expired} {incr string_changed{string_foo}} + {incr before_overwritten} {incr string_changed{string_bar}} {incr string_total} {incr string_total} diff --git a/tests/unit/moduleapi/postnotifications.tcl b/tests/unit/moduleapi/postnotifications.tcl index 11b003a15d06..b281a66c5554 100644 --- a/tests/unit/moduleapi/postnotifications.tcl +++ b/tests/unit/moduleapi/postnotifications.tcl @@ -9,7 +9,7 @@ tags "modules" { r set string_x 1 assert_equal {1} [r get string_changed{string_x}] assert_equal {1} [r get string_total] - + r set string_x 2 assert_equal {2} [r get string_changed{string_x}] assert_equal {2} [r get string_total] @@ -23,6 +23,7 @@ tags "modules" { {exec} {multi} {set string_x 2} + {incr before_overwritten} {incr string_changed{string_x}} {incr string_total} {exec} @@ -37,7 +38,7 @@ tags "modules" { assert_equal {OK} [r postnotification.async_set] assert_equal {1} [r get string_changed{string_x}] assert_equal {1} [r get string_total] - + assert_replication_stream $repl { {multi} {select *} @@ -69,6 +70,7 @@ tags "modules" { {pexpireat x *} {multi} {del x} + {incr before_expired} {incr expired} {exec} } @@ -91,6 +93,7 @@ tags "modules" { {pexpireat x *} {multi} {del x} + {incr before_expired} {incr expired} {exec} } @@ -115,6 +118,7 @@ tags "modules" { {multi} {set read_x 1} {del x} + {incr before_expired} {incr expired} {exec} } @@ -143,7 +147,7 @@ tags "modules" { r flushall set repl [attach_to_replication_stream] r set x 1 - r config set maxmemory-policy allkeys-random + r config set maxmemory-policy allkeys-random r config set maxmemory 1 assert_error {OOM *} {r set y 1} @@ -153,6 +157,7 @@ tags "modules" { {set x 1} {multi} {del x} + {incr before_evicted} {incr evicted} {exec} } @@ -172,7 +177,7 @@ tags "modules" { r set string_x 1 assert_equal {1} [r get string_changed{string_x}] assert_equal {1} [r get string_total] - + r set string_x 2 assert_equal {2} [r get string_changed{string_x}] assert_equal {2} [r get string_total] @@ -190,6 +195,7 @@ tags "modules" { {exec} {multi} {set string_x 2} + {incr before_overwritten} {incr string_changed{string_x}} {incr string_total} {exec} @@ -202,4 +208,4 @@ tags "modules" { close_replication_stream $repl } } -} \ No newline at end of file +}