mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 08:08:53 -05:00
WATCH is now able to detect keys removed by FLUSHALL and FLUSHDB
This commit is contained in:
parent
c20c189db5
commit
9b30e1a207
30
redis.c
30
redis.c
@ -637,6 +637,7 @@ static int rewriteAppendOnlyFileBackground(void);
|
||||
static int vmSwapObjectBlocking(robj *key, robj *val);
|
||||
static int prepareForShutdown();
|
||||
static void touchWatchedKey(redisDb *db, robj *key);
|
||||
static void touchWatchedKeysOnFlush(int dbid);
|
||||
static void unwatchAllKeys(redisClient *c);
|
||||
|
||||
static void authCommand(redisClient *c);
|
||||
@ -6780,12 +6781,14 @@ static void convertToRealHash(robj *o) {
|
||||
|
||||
static void flushdbCommand(redisClient *c) {
|
||||
server.dirty += dictSize(c->db->dict);
|
||||
touchWatchedKeysOnFlush(c->db->id);
|
||||
dictEmpty(c->db->dict);
|
||||
dictEmpty(c->db->expires);
|
||||
addReply(c,shared.ok);
|
||||
}
|
||||
|
||||
static void flushallCommand(redisClient *c) {
|
||||
touchWatchedKeysOnFlush(-1);
|
||||
server.dirty += emptyDb();
|
||||
addReply(c,shared.ok);
|
||||
if (server.bgsavechildpid != -1) {
|
||||
@ -10475,6 +10478,33 @@ static void touchWatchedKey(redisDb *db, robj *key) {
|
||||
}
|
||||
}
|
||||
|
||||
/* On FLUSHDB or FLUSHALL all the watched keys that are present before the
|
||||
* flush but will be deleted as effect of the flushing operation should
|
||||
* be touched. "dbid" is the DB that's getting the flush. -1 if it is
|
||||
* a FLUSHALL operation (all the DBs flushed). */
|
||||
static void touchWatchedKeysOnFlush(int dbid) {
|
||||
listIter li1, li2;
|
||||
listNode *ln;
|
||||
|
||||
/* For every client, check all the waited keys */
|
||||
listRewind(server.clients,&li1);
|
||||
while((ln = listNext(&li1))) {
|
||||
redisClient *c = listNodeValue(ln);
|
||||
listRewind(c->watched_keys,&li2);
|
||||
while((ln = listNext(&li2))) {
|
||||
watchedKey *wk = listNodeValue(ln);
|
||||
|
||||
/* For every watched key matching the specified DB, if the
|
||||
* key exists, mark the client as dirty, as the key will be
|
||||
* removed. */
|
||||
if (dbid == -1 || wk->db->id == dbid) {
|
||||
if (dictFind(wk->db->dict, wk->key) != NULL)
|
||||
c->flags |= REDIS_DIRTY_CAS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void watchCommand(redisClient *c) {
|
||||
int j;
|
||||
|
||||
|
@ -15,6 +15,7 @@ proc test {name code okpattern} {
|
||||
puts $warnings
|
||||
}
|
||||
}
|
||||
puts "Script died with $error"
|
||||
exit 1
|
||||
}
|
||||
if {$okpattern eq $retval || [string match $okpattern $retval]} {
|
||||
|
@ -63,4 +63,52 @@ start_server default.conf {} {
|
||||
test {UNWATCH when there is nothing watched works as expected} {
|
||||
r unwatch
|
||||
} {OK}
|
||||
|
||||
test {FLUSHALL is able to touch the watched keys} {
|
||||
r set x 30
|
||||
r watch x
|
||||
r flushall
|
||||
r multi
|
||||
r ping
|
||||
r exec
|
||||
} {}
|
||||
|
||||
test {FLUSHALL does not touch non affected keys} {
|
||||
r del x
|
||||
r watch x
|
||||
r flushall
|
||||
r multi
|
||||
r ping
|
||||
r exec
|
||||
} {PONG}
|
||||
|
||||
test {FLUSHDB is able to touch the watched keys} {
|
||||
r set x 30
|
||||
r watch x
|
||||
r flushdb
|
||||
r multi
|
||||
r ping
|
||||
r exec
|
||||
} {}
|
||||
|
||||
test {FLUSHDB does not touch non affected keys} {
|
||||
r del x
|
||||
r watch x
|
||||
r flushdb
|
||||
r multi
|
||||
r ping
|
||||
r exec
|
||||
} {PONG}
|
||||
|
||||
test {WATCH is able to remember the DB a key belongs to} {
|
||||
r select 5
|
||||
r set x 30
|
||||
r watch x
|
||||
r select 1
|
||||
r set x 10
|
||||
r select 5
|
||||
r multi
|
||||
r ping
|
||||
r exec
|
||||
} {PONG}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user