fix(redisSessions): improve redis session lookup performance (#2026) r=vladikoff,rfk

Fixes #2025
This commit is contained in:
Udara Weerasinghege 2017-07-31 09:35:43 -04:00 коммит произвёл Vlad Filippov
Родитель 8c1d7f2f73
Коммит b533fb935d
2 изменённых файлов: 29 добавлений и 28 удалений

Просмотреть файл

@ -270,9 +270,9 @@ module.exports = (
}
// for each db session token, if there is a matching redis token
// overwrite the properties of the db token with the redis token values
const redisSessionTokens = redisTokens ? JSON.parse(redisTokens) : []
const redisSessionTokens = redisTokens ? JSON.parse(redisTokens) : {}
const sessions = mysqlSessionTokens.map((sessionToken) => {
const redisToken = redisSessionTokens.find(tok => tok.tokenId === sessionToken.tokenId)
const redisToken = redisSessionTokens[sessionToken.tokenId]
const mergedToken = Object.assign({}, sessionToken, redisToken)
return mergedToken
})
@ -431,7 +431,7 @@ module.exports = (
}
return P.all(promises)
.spread((devices, redisTokens) => {
const redisSessionTokens = redisTokens ? JSON.parse(redisTokens) : []
const redisSessionTokens = redisTokens ? JSON.parse(redisTokens) : {}
log.info({
op: 'db.devices.redisSessionTokens',
hasRedisTokens: !! redisSessionTokens.length,
@ -440,7 +440,7 @@ module.exports = (
// for each device, if there is a redis token with a matching tokenId
// overwrite device's ua properties and lastAccessTime with redis token values
return devices.map(device => {
const token = redisSessionTokens.find(tok => tok.tokenId === device.sessionTokenId)
const token = redisSessionTokens[device.sessionTokenId]
const mergedInfo = Object.assign({}, device, token)
return {
id: device.id,
@ -513,18 +513,16 @@ module.exports = (
lastAccessTime: token.lastAccessTime,
createdAt: token.createdAt
}]
let sessionTokens = []
// get the array of session tokens associated with the given uid
let sessionTokens
// get the object of session tokens associated with the given uid
return this.redis.getAsync(uid)
.then(res => {
if (res) {
res = JSON.parse(res)
// remove the token that we want to update from the array
const filteredRes = res.filter(tok => tok.tokenId !== token.id)
sessionTokens = sessionTokens.concat(filteredRes)
}
// add new updated token into array, and set the resulting array as the new value
sessionTokens = sessionTokens.concat(newToken)
// update the hash with the new token
sessionTokens = res ? JSON.parse(res) : {}
sessionTokens[token.id] = newToken
return sessionTokens
})
.then(() => {
return this.redis.setAsync(uid, JSON.stringify(sessionTokens))
})
.then(() => sessionTokens)
@ -654,9 +652,8 @@ module.exports = (
}
return P.all(promises)
.spread((deleteRes, redisTokens) => {
const redisSessionTokens = redisTokens ? JSON.parse(redisTokens) : []
const tokenToDeleteIndex = redisSessionTokens.findIndex((tok) => tok.tokenId === sessionToken.id)
redisSessionTokens.splice(tokenToDeleteIndex, 1)
const redisSessionTokens = redisTokens ? JSON.parse(redisTokens) : {}
delete redisSessionTokens[ sessionToken.id]
return this.redis.setAsync(uid, JSON.stringify(redisSessionTokens))
})
}

Просмотреть файл

@ -201,7 +201,7 @@ describe('remote db', function() {
assert.equal(redisSetSpy.lastCall.args[0], account.uid)
const redisSetArgs = JSON.parse(redisSetSpy.lastCall.args[1])
const token = redisSetArgs[0]
const token = redisSetArgs[tokenId]
assert.equal(token.tokenId, tokenId)
assert.equal(token.uid, account.uid)
assert.equal(token.uaBrowser, 'Firefox')
@ -239,20 +239,23 @@ describe('remote db', function() {
return sessionToken
})
.then(function(sessionToken) {
const mockTokens = JSON.stringify([{
uid: sessionToken.uid,
id: 'idToNotDelete'
}, {
uid: sessionToken.uid,
id: sessionToken.id
}])
const mockTokens = JSON.stringify({
idToNotDelete: {
uid: sessionToken.uid,
id: 'idToNotDelete'
},
[sessionToken.id]: {
uid: sessionToken.uid,
id: sessionToken.id
}
})
redisGetSpy.returns(P.resolve(mockTokens))
return db.deleteSessionToken(sessionToken)
})
.then(function() {
const redisSetArgs = JSON.parse(redisSetSpy.lastCall.args[1])
assert.equal(redisSetArgs.length, 1)
assert.equal(redisSetArgs[0].id, 'idToNotDelete')
assert.equal(Object.keys(redisSetArgs).length, 1)
assert.ok(redisSetArgs.idToNotDelete)
return db.sessionToken(tokenId)
.then(function(sessionToken) {
@ -383,7 +386,8 @@ describe('remote db', function() {
})
})
.then(results => {
redisGetSpy.returns(P.resolve(JSON.stringify(results[1])))
const tokenToReturn = results[1][sessionToken.tokenId]
redisGetSpy.returns(P.resolve(JSON.stringify({[sessionToken.tokenId]: tokenToReturn})))
// Create another session token
return db.createSessionToken(sessionToken, 'Mozilla/5.0 (Android 7.1.2; Mobile; rv:56.0) Gecko/56.0 Firefox/56.0')