From 3570629f9006687177b86f279ea9a6b2e8690e67 Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 11 Nov 2011 17:16:03 +0100 Subject: [PATCH 1/3] set default client timeout to zero inside redis.h as well --- src/redis.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redis.h b/src/redis.h index d660cae9..79ff3a6a 100644 --- a/src/redis.h +++ b/src/redis.h @@ -39,7 +39,7 @@ /* Static server configuration */ #define REDIS_SERVERPORT 6379 /* TCP port */ -#define REDIS_MAXIDLETIME (60*5) /* default client timeout */ +#define REDIS_MAXIDLETIME 0 /* default client timeout: infinite */ #define REDIS_IOBUF_LEN (1024*16) #define REDIS_LOADBUF_LEN 1024 #define REDIS_DEFAULT_DBNUM 16 From 4be855e757b800a9f848823fcee8b7faf3e1eba0 Mon Sep 17 00:00:00 2001 From: antirez Date: Sat, 12 Nov 2011 01:04:27 +0100 Subject: [PATCH 2/3] Fixed issues with expire introduced with latest millisecond resolution feature. Many time_t were not converted to long long, and one time() call was not replaced with mstime(). --- src/aof.c | 4 ++-- src/debug.c | 2 +- src/rdb.c | 2 +- src/redis.c | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/aof.c b/src/aof.c index 8f3f5d59..4a463bde 100644 --- a/src/aof.c +++ b/src/aof.c @@ -431,7 +431,7 @@ int rewriteAppendOnlyFile(char *filename) { FILE *fp; char tmpfile[256]; int j; - time_t now = time(NULL); + long long now = mstime(); /* Note that we have to use a different temp name here compared to the * one used by rewriteAppendOnlyFileBackground() function. */ @@ -462,7 +462,7 @@ int rewriteAppendOnlyFile(char *filename) { while((de = dictNext(di)) != NULL) { sds keystr; robj key, *o; - time_t expiretime; + long long expiretime; keystr = dictGetKey(de); o = dictGetVal(de); diff --git a/src/debug.c b/src/debug.c index 2dfe2280..376e0712 100644 --- a/src/debug.c +++ b/src/debug.c @@ -91,7 +91,7 @@ void computeDatasetDigest(unsigned char *final) { while((de = dictNext(di)) != NULL) { sds key; robj *keyobj, *o; - time_t expiretime; + long long expiretime; memset(digest,0,20); /* This key-val digest */ key = dictGetKey(de); diff --git a/src/rdb.c b/src/rdb.c index e11f5c9c..2c0feb6d 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -597,7 +597,7 @@ int rdbSave(char *filename) { dictEntry *de; char tmpfile[256]; int j; - time_t now = mstime(); + long long now = mstime(); FILE *fp; rio rdb; diff --git a/src/redis.c b/src/redis.c index 7d209439..23b7b280 100644 --- a/src/redis.c +++ b/src/redis.c @@ -562,17 +562,17 @@ void activeExpireCycle(void) { * of the keys were expired. */ do { long num = dictSize(db->expires); - time_t now = time(NULL); + long long now = mstime(); expired = 0; if (num > REDIS_EXPIRELOOKUPS_PER_CRON) num = REDIS_EXPIRELOOKUPS_PER_CRON; while (num--) { dictEntry *de; - time_t t; + long long t; if ((de = dictGetRandomKey(db->expires)) == NULL) break; - t = (time_t) dictGetVal(de); + t = dictGetSignedIntegerVal(de); if (now > t) { sds key = dictGetKey(de); robj *keyobj = createStringObject(key,sdslen(key)); From 762eea07cac57eecb89bf5a079139cd664f4b9d8 Mon Sep 17 00:00:00 2001 From: antirez Date: Sat, 12 Nov 2011 11:27:38 +0100 Subject: [PATCH 3/3] Added test to make sure Redis evicts expired keys actively (and not just in a lazy fashion). --- tests/unit/expire.tcl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/unit/expire.tcl b/tests/unit/expire.tcl index 6130e842..b88ff821 100644 --- a/tests/unit/expire.tcl +++ b/tests/unit/expire.tcl @@ -127,4 +127,18 @@ start_server {tags {"expire"}} { set ttl [r pttl x] assert {$ttl > 900 && $ttl <= 1000} } + + test {Redis should actively expire keys incrementally} { + r flushdb + r psetex key1 500 a + r psetex key2 500 a + r psetex key3 500 a + set size1 [r dbsize] + # Redis expires random keys ten times every second so we are + # fairly sure that all the three keys should be evicted after + # one second. + after 1000 + set size2 [r dbsize] + list $size1 $size2 + } {3 0} }