-
-
Save harbhub/cf04adce77de3a02f8db to your computer and use it in GitHub Desktop.
get an object from redis, modify contents, and set
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Bluebird = require('bluebird'); | |
var redis = require('redis'); | |
var _ = require('lodash'); | |
function getSet(key, transmute){ | |
return new Bluebird(function(resolve, reject){ | |
function setAtomic(key, count){ | |
var counts = count; | |
// create a UNIQUE CLIENT CONNECTION for this process | |
var atomicClient = redis.createClient(); | |
atomicClient.watch(key); | |
// get the object | |
atomicClient.hgetall(key, function(err,o){ | |
var newO = {}; | |
if(err){ | |
return reject(err); | |
} | |
// get parsed object | |
var generated = Object.keys(o).reduce(function(generated, field){ | |
var val; | |
try { | |
val = JSON.parse(o[field]); | |
} | |
catch (e){ | |
val = ''; | |
} | |
generated[field] = val; | |
return generated; | |
},{}); | |
// run the transmute function | |
newO = transmute(generated); | |
// update all keys | |
var chain = Object.keys(newO).reduce(function(ch, field){ | |
var val = typeof newO[field] === 'string' ? newO[field] : JSON.stringify(newO[field]); | |
return ch.hset(key, field, val); | |
}, atomicClient.multi()); | |
var k1 = Object.keys(o); | |
var k2 = Object.keys(newO); | |
// remove the keys from redis that are no longer in the object (after transmuting) | |
var keysToRemove = _.difference(k1, k2); | |
var nextChain = keysToRemove.reduce(function(ch, field){ | |
return ch.hdel(key, field); | |
}, chain); | |
nextChain.hgetall(key).exec(function(err, results){ | |
atomicClient.quit(); | |
if(results === null && counts < 10){ | |
setAtomic(key, counts++); | |
} | |
if(results === null && counts >= 10){ | |
return reject(new Error("Could not complete transaction")); | |
} | |
if(err){ | |
return reject(err); | |
} | |
return resolve(results); | |
}); | |
}); | |
} | |
setAtomic(key, 0); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment