Skip to content

Instantly share code, notes, and snippets.

@Mumakil
Last active August 29, 2015 14:16
Show Gist options
  • Save Mumakil/38049fb57c7a317be670 to your computer and use it in GitHub Desktop.
Save Mumakil/38049fb57c7a317be670 to your computer and use it in GitHub Desktop.
Redis expire notification test

Redis expire test

Test script to check how redis expire registration works.

Running

Run with npm run.

const redis = require('redis'),
subscriber = redis.createClient(6379, 'localhost'),
writer = redis.createClient(6379, 'localhost'),
keys = new Map();
// config
const keyCount = 10000,
delay = 10, // expire delay in seconds
listenDelay = 5, // how many seconds to listen after last timeout
batchDelay = 1, // how many seconds between a batch
batches = 20; // In how many batches to execute
subscriber.on('pmessage', (pattern, channel, message) => {
if (message == 'expired') {
const parts = channel.split(':'),
key = Number(parts[2]),
keyData = keys.get(key);
keyData.unset = Date.now();
keyData.delay = keyData.unset - keyData.set - delay * 1000;
}
});
function setExpiringBatch(start, count, cb) {
for (let i = 0; i < count; i += 1) {
const key = i + start;
writer.setex(`expire-test:${key}`, delay, Date.now());
keys.set(key, { set: Date.now(), unset: undefined, delay: 0 });
}
console.log(`Added ${count} test keys with ${delay}s expire time.`);
cb(start + count);
}
subscriber.on('psubscribe', (channel, count) => {
console.log("Subscribed to keychange events.");
const more = (last) => {
if (last < keyCount) {
console.log('Sleeping for', batchDelay, 's')
setTimeout(() => {
setExpiringBatch(last + 1, keyCount / batches, more);
}, batchDelay * 1000);
} else {
setTimeout(() => {
console.log(`Listened for ${listenDelay + delay}s, shutting down.`);
subscriber.punsubscribe("__keyspace@0__:*");
subscriber.quit();
writer.quit();
const keyValues = keys.values();
let unexpiredCount = 0,
biggestDelay = 0,
delays = [];
for (let keyData of keyValues) {
if (!keyData.unset)
unexpiredCount += 1;
else
if (keyData.delay > biggestDelay)
biggestDelay = keyData.delay;
delays.push(keyData.delay);
}
delays.sort();
console.log("Results for expire test:");
console.log("Created", keyCount, "expiring keys with", delay, "s expire time in", batches, "batches with", batchDelay, "s between each batch.");
console.log("Keys that did not expire: ", unexpiredCount);
console.log("Biggest delay was:", biggestDelay, "ms");
console.log("Median delay was: ", delays[Math.floor(delays.length / 2)], "ms");
console.log("Mean delay was: ", Math.floor(delays.reduce((memo, count) => { return memo + count; }, 0) / delays.length), "ms");
}, (listenDelay + delay) * 1000);
}
}
setExpiringBatch(0, keyCount / batches, more);
});
writer.keys("expire-test:*", (err, keys) => {
console.log(`Found ${keys.length} existing keys.`);
if (keys.length > 0) {
console.log("Deleting existing keys.");
writer.del(...keys);
}
subscriber.config("SET", "notify-keyspace-events", "Kx");
subscriber.psubscribe("__keyspace@0__:*");
});
{
"name": "redis-expire-test",
"version": "0.0.1",
"description": "Test redis key expiration",
"main": "index.js",
"scripts": {
"test": "./node_modules/.bin/babel-node index.es6"
},
"author": "Otto Vehvilainen",
"license": "MIT",
"dependencies": {
"babel": "^4.5.5",
"hiredis": "^0.2.0",
"redis": "^0.12.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment