@colu-legacy/community-cache
Version:
Colu's community cache based on Redis
152 lines (133 loc) • 4.61 kB
JavaScript
module.exports = function (config) {
var redis = require('redis')
var srandom = require('secure-random')
var async = require('async')
var redisClient = redis.createClient(parseInt(config.get('redis_port') || '6379', 10), config.get('redis_host'))
function store () {}
store.redisClient = redisClient
store.getNextAccountIndex = function (seed, callback) {
store.redisClient.incr(createKey('index:' + seed), callback)
}
store.getCurrentAccountIndex = function (seed, callback) {
store.redisClient.get(createKey('index:' + seed), callback)
}
store.saveCurrencyKey = function (index, key, callback) {
store.redisClient.hset(createKey('keys'), index, key, callback)
}
store.getCurrencyKey = function (index, callback) {
store.redisClient.hget(createKey('keys'), index, callback)
}
store.getCommunity = function (id, callback) {
store.redisClient.get(createKey('community:' + id), callback)
}
store.saveCommunity = function (data, callback) {
var multi = store.redisClient.multi()
multi.set(createKey('community:' + data.id), JSON.stringify(data))
// TODO: once we implement multiple managers we need to make sure indexs are update in comm_managers
multi.exec(callback)
}
store.getSeed = function (callback) {
var newseed = srandom.randomBuffer(32).toString('hex')
var seedKey = createKey('seed')
var seed
async.waterfall([
function (cb) {
store.redisClient.setnx(seedKey, newseed, cb)
},
function (res, cb) {
store.redisClient.get(seedKey, cb)
},
function (seedInRedis, cb) {
seed = seedInRedis
if (seed !== newseed) return cb()
store.redisClient.set(createKey('index:' + seed), 0, cb)
}
],
function (err, res) {
callback(err, seed)
})
}
store.createCommunity = function (community, callback) {
store.redisClient.watch(createKey('community:id'))
store.redisClient.get(createKey('community:id'), function (err, data) {
if (err) return callback(err)
var multi = store.redisClient.multi()
var id = community.id = parseInt(data || 0) + 1
multi.set(createKey('community:' + id), JSON.stringify(community))
multi.sadd(createKey('comm_managers:' + community.owner), id)
multi.incr(createKey('community:id'))
store.redisClient.hsetnx(createKey('community:nametoid'), community.name, id, function (err, count) {
if (err) return callback(err)
if (count === 0) {
multi.discard()
err = new Error('community ' + community.name + ' already exists')
err.status = 403
callback(err)
} else {
multi.exec(function (err, data) {
callback(err, data[1])
})
}
})
})
}
store.get = function (key, callback) {
store.redisClient.get(createKey(key), function(err, val) {
if(err) {
return callback(err)
}
if(!val) {
return callback()
}
try {
var data = JSON.parse(val)
return callback(null, data)
} catch (e) {
return callback(null, e)
}
})
}
store.set = function (key, value, expirySecs, callback) {
if(expirySecs) {
store.redisClient.set(createKey(key), JSON.stringify(value), 'EX', expirySecs, callback)
} else {
store.redisClient.set(createKey(key), JSON.stringify(value), callback)
}
}
store.keys = function (key, callback) {
store.redisClient.keys(createKey(key), callback)
}
store.del = function (key, callback) {
store.redisClient.del(createKey(key), callback)
}
function createKey (key) {
var envType = config.get('env_type') + ':'
var basePrefix = 'ccs:store:'
var networkPrefix = ((config.get('testnet') !== 'false') ? 'tn' : 'mn') + ':'
// console.log('createKey for sdk: ', basePrefix + envType + networkPrefix + key)
if(key.indexOf(basePrefix + envType + networkPrefix) > -1) {
return key
}
return basePrefix + envType + networkPrefix + key
}
function parallelRedisJson (commands, callback) {
var response = []
async.each(commands,
function (command, callback) {
var rcommand = command.shift()
command.push(function (err, data) {
var json = null
try {
json = JSON.parse(data)
} catch (e) {}
response.push(json || data)
callback(err)
})
store.redisClient[rcommand](command)
},
function (err) {
callback(err, response)
})
}
return store
}