Set CLIENT_DIRTY_CAS to all clients of DB when DB is dirty. * It may happen in the following situations: * FLUSHDB, FLUSHALL, SWAPDB * * replaced_with: for SWAPDB, the WATCH should be invalidated if * the key exists in either of them, and skipped only if it * doesn't exist in both. */
| 403 | * the key exists in either of them, and skipped only if it |
| 404 | * doesn't exist in both. */ |
| 405 | void touchAllWatchedKeysInDb(redisDb *emptied, redisDb *replaced_with) { |
| 406 | listIter li; |
| 407 | listNode *ln; |
| 408 | dictEntry *de; |
| 409 | |
| 410 | serverAssert(GlobalLocksAcquired()); |
| 411 | |
| 412 | if (dictSize(emptied->watched_keys) == 0) return; |
| 413 | |
| 414 | dictIterator *di = dictGetSafeIterator(emptied->watched_keys); |
| 415 | while((de = dictNext(di)) != NULL) { |
| 416 | robj *key = (robj*)de->key; |
| 417 | list *clients = (list*)de->v.val; |
| 418 | if (!clients) continue; |
| 419 | listRewind(clients,&li); |
| 420 | while((ln = listNext(&li))) { |
| 421 | client *c = (client*)listNodeValue(ln); |
| 422 | if (emptied->find(key)) { |
| 423 | c->flags |= CLIENT_DIRTY_CAS; |
| 424 | } else if (replaced_with && replaced_with->find(key)) { |
| 425 | c->flags |= CLIENT_DIRTY_CAS; |
| 426 | } |
| 427 | } |
| 428 | } |
| 429 | dictReleaseIterator(di); |
| 430 | } |
| 431 | |
| 432 | void watchCommand(client *c) { |
| 433 | int j; |
no test coverage detected