express-redis-cache icon indicating copy to clipboard operation
express-redis-cache copied to clipboard

Replace hmset/expire/hgetall with set/get

Open joshk0 opened this issue 3 years ago • 1 comments

In the original implementation, there is a risk of an infinitely long-lived cache key that arises if HMSET for the cache entry succeeds, but EXPIRE fails or is not executed for any reason.

By serializing the cache entry to JSON and storing that single string in Redis, we can take advantage of SET's ability to atomically accept an EX-piration time along with the set.

The downside is we now have to do a JSON.stringify for every cache store we do, and JSON.parse for every cache hit / retrieval, but that is better than cache entries that never expire.

Tests pass against a local redis after modifying 1 test case which stores a value then stores the same key again without cache. In the HMSET implementation, this test passed because HMSET does not modify the expiration date of existing keys. However, calls to SET always remove old values and any expiration.

Fixes #101.

joshk0 avatar Jul 13 '20 21:07 joshk0

Output of redis-cli monitor during the changed unit test:

1594676437.435326 [0 127.0.0.1:40264] "set" "erct:test1" "{\"body\":\"test1 test1 test1\",\"type\":\"text/html\",\"status\":200,\"touched\":1594676437434,\"expire\":2}" "EX" "2"
1594676437.438695 [0 127.0.0.1:40264] "set" "erct:i don't expire" "{\"body\":\"test1 test1 test1\",\"type\":\"text/html\",\"status\":200,\"touched\":1594676437438,\"expire\":0}"

joshk0 avatar Jul 13 '20 21:07 joshk0