mirror of
https://github.com/fluencelabs/redis
synced 2025-04-07 01:51:05 +00: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 vmSwapObjectBlocking(robj *key, robj *val);
|
||||||
static int prepareForShutdown();
|
static int prepareForShutdown();
|
||||||
static void touchWatchedKey(redisDb *db, robj *key);
|
static void touchWatchedKey(redisDb *db, robj *key);
|
||||||
|
static void touchWatchedKeysOnFlush(int dbid);
|
||||||
static void unwatchAllKeys(redisClient *c);
|
static void unwatchAllKeys(redisClient *c);
|
||||||
|
|
||||||
static void authCommand(redisClient *c);
|
static void authCommand(redisClient *c);
|
||||||
@ -6780,12 +6781,14 @@ static void convertToRealHash(robj *o) {
|
|||||||
|
|
||||||
static void flushdbCommand(redisClient *c) {
|
static void flushdbCommand(redisClient *c) {
|
||||||
server.dirty += dictSize(c->db->dict);
|
server.dirty += dictSize(c->db->dict);
|
||||||
|
touchWatchedKeysOnFlush(c->db->id);
|
||||||
dictEmpty(c->db->dict);
|
dictEmpty(c->db->dict);
|
||||||
dictEmpty(c->db->expires);
|
dictEmpty(c->db->expires);
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flushallCommand(redisClient *c) {
|
static void flushallCommand(redisClient *c) {
|
||||||
|
touchWatchedKeysOnFlush(-1);
|
||||||
server.dirty += emptyDb();
|
server.dirty += emptyDb();
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
if (server.bgsavechildpid != -1) {
|
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) {
|
static void watchCommand(redisClient *c) {
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ proc test {name code okpattern} {
|
|||||||
puts $warnings
|
puts $warnings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
puts "Script died with $error"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
if {$okpattern eq $retval || [string match $okpattern $retval]} {
|
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} {
|
test {UNWATCH when there is nothing watched works as expected} {
|
||||||
r unwatch
|
r unwatch
|
||||||
} {OK}
|
} {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…
x
Reference in New Issue
Block a user