diff options
author | Huang Zhw <huang_zhw@126.com> | 2022-11-30 17:56:36 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-30 11:56:36 +0200 |
commit | c81813148b71cd4be686402ef69f628f67dbb8c4 (patch) | |
tree | 54a5f6bc0701c97db66cb1cebe85fecfa3181429 /src/server.h | |
parent | 7dfd7b9197bbe216912049eebecbda3f1684925e (diff) | |
download | redis-c81813148b71cd4be686402ef69f628f67dbb8c4.tar.gz |
Add a special notification unlink available only for modules (#9406)
Add a new module event `RedisModule_Event_Key`, this event is fired
when a key is removed from the keyspace.
The event includes an open key that can be used for reading the key before
it is removed. Modules can also extract the key-name, and use RM_Open
or RM_Call to access key from within that event, but shouldn't modify anything
from within this event.
The following sub events are available:
- `REDISMODULE_SUBEVENT_KEY_DELETED`
- `REDISMODULE_SUBEVENT_KEY_EXPIRED`
- `REDISMODULE_SUBEVENT_KEY_EVICTED`
- `REDISMODULE_SUBEVENT_KEY_OVERWRITE`
The data pointer can be casted to a RedisModuleKeyInfo structure
with the following fields:
```
RedisModuleKey *key; // Opened Key
```
### internals
* We also add two dict functions:
`dictTwoPhaseUnlinkFind` finds an element from the table, also get the plink of the entry.
The entry is returned if the element is found. The user should later call `dictTwoPhaseUnlinkFree`
with it in order to unlink and release it. Otherwise if the key is not found, NULL is returned.
These two functions should be used in pair. `dictTwoPhaseUnlinkFind` pauses rehash and
`dictTwoPhaseUnlinkFree` resumes rehash.
* We change `dbOverwrite` to `dbReplaceValue` which just replaces the value of the key and
doesn't fire any events. The "overwrite" part (which emits events) is just when called from `setKey`,
the other places that called dbOverwrite were ones that just update the value in-place (INCR*, SPOP,
and dbUnshareStringValue). This should not have any real impact since `moduleNotifyKeyUnlink` and
`signalDeletedKeyAsReady` wouldn't have mattered in these cases anyway (i.e. module keys and
stream keys didn't have direct calls to dbOverwrite)
* since we allow doing RM_OpenKey from withing these callbacks, we temporarily disable lazy expiry.
* We also temporarily disable lazy expiry when we are in unlink/unlink2 callback and keyspace
notification callback.
* Move special definitions to the top of redismodule.h
This is needed to resolve compilation errors with RedisModuleKeyInfoV1
that carries a RedisModuleKey member.
Co-authored-by: Oran Agra <oran@redislabs.com>
Diffstat (limited to 'src/server.h')
-rw-r--r-- | src/server.h | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/src/server.h b/src/server.h index 190664ded..9dfbf81b7 100644 --- a/src/server.h +++ b/src/server.h @@ -291,6 +291,13 @@ extern int configOOMScoreAdjValuesDefaults[CONFIG_OOM_COUNT]; /* Key flags for when access type is unknown */ #define CMD_KEY_FULL_ACCESS (CMD_KEY_RW | CMD_KEY_ACCESS | CMD_KEY_UPDATE) +/* Key flags for how key is removed */ +#define DB_FLAG_KEY_NONE 0 +#define DB_FLAG_KEY_DELETED (1ULL<<0) +#define DB_FLAG_KEY_EXPIRED (1ULL<<1) +#define DB_FLAG_KEY_EVICTED (1ULL<<2) +#define DB_FLAG_KEY_OVERWRITE (1ULL<<3) + /* Channel flags share the same flag space as the key flags */ #define CMD_CHANNEL_PATTERN (1ULL<<11) /* The argument is a channel pattern */ #define CMD_CHANNEL_SUBSCRIBE (1ULL<<12) /* The command subscribes to channels */ @@ -1648,6 +1655,7 @@ struct redisServer { int tcpkeepalive; /* Set SO_KEEPALIVE if non-zero. */ int active_expire_enabled; /* Can be disabled for testing purposes. */ int active_expire_effort; /* From 1 (default) to 10, active effort. */ + int lazy_expire_disabled; /* If > 0, don't trigger lazy expire */ int active_defrag_enabled; int sanitize_dump_payload; /* Enables deep sanitization for ziplist and listpack in RDB and RESTORE. */ int skip_checksum_validation; /* Disable checksum validation for RDB and RESTORE payload. */ @@ -2440,7 +2448,7 @@ void moduleUnblockClient(client *c); int moduleBlockedClientMayTimeout(client *c); int moduleClientIsBlockedOnKeys(client *c); void moduleNotifyUserChanged(client *c); -void moduleNotifyKeyUnlink(robj *key, robj *val, int dbid); +void moduleNotifyKeyUnlink(robj *key, robj *val, int dbid, int flags); size_t moduleGetFreeEffort(robj *key, robj *val, int dbid); size_t moduleGetMemUsage(robj *key, robj *val, size_t sample_size, int dbid); robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj *value); @@ -3154,7 +3162,7 @@ int objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle, void dbAdd(redisDb *db, robj *key, robj *val); int dbAddRDBLoad(redisDb *db, sds key, robj *val); -void dbOverwrite(redisDb *db, robj *key, robj *val); +void dbReplaceValue(redisDb *db, robj *key, robj *val); #define SETKEY_KEEPTTL 1 #define SETKEY_NO_SIGNAL 2 @@ -3162,6 +3170,7 @@ void dbOverwrite(redisDb *db, robj *key, robj *val); #define SETKEY_DOESNT_EXIST 8 void setKey(client *c, redisDb *db, robj *key, robj *val, int flags); robj *dbRandomKey(redisDb *db); +int dbGenericDelete(redisDb *db, robj *key, int async, int flags); int dbSyncDelete(redisDb *db, robj *key); int dbDelete(redisDb *db, robj *key); robj *dbUnshareStringValue(redisDb *db, robj *key, robj *o); |