Skip to content

Commit

Permalink
Add in-memory user cache
Browse files Browse the repository at this point in the history
  • Loading branch information
mikiher committed Nov 10, 2024
1 parent 2e970cb commit a382482
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 25 deletions.
30 changes: 10 additions & 20 deletions server/Auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -990,28 +990,18 @@ class Auth {
})
}
}

Database.userModel
.update(
{
pash: pw
},
{
where: { id: matchingUser.id }
}
)
.then(() => {
Logger.info(`[Auth] User "${matchingUser.username}" changed password`)
res.json({
success: true
})
try {
await matchingUser.update({ pash: pw })
Logger.info(`[Auth] User "${matchingUser.username}" changed password`)
res.json({
success: true
})
.catch((error) => {
Logger.error(`[Auth] User "${matchingUser.username}" failed to change password`, error)
res.json({
error: 'Unknown error'
})
} catch (error) {
Logger.error(`[Auth] User "${matchingUser.username}" failed to change password`, error)
res.json({
error: 'Unknown error'
})
}
}
}

Expand Down
112 changes: 107 additions & 5 deletions server/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,53 @@ const sequelize = require('sequelize')
const Logger = require('../Logger')
const SocketAuthority = require('../SocketAuthority')
const { isNullOrNaN } = require('../utils')
const { LRUCache } = require('lru-cache')

class UserCache {
constructor() {
this.cache = new LRUCache({ max: 100 })
}

getById(id) {
const user = this.cache.get(id)
return user
}

getByEmail(email) {
const user = this.cache.find((u) => u.email === email)
return user
}

getByUsername(username) {
const user = this.cache.find((u) => u.username === username)
return user
}

getByOldId(oldUserId) {
const user = this.cache.find((u) => u.extraData?.oldUserId === oldUserId)
return user
}

getByOpenIDSub(sub) {
const user = this.cache.find((u) => u.extraData?.authOpenIDSub === sub)
return user
}

set(user) {
user.fromCache = true
this.cache.set(user.id, user)
}

delete(userId) {
this.cache.delete(userId)
}

maybeInvalidate(user) {
if (!user.fromCache) this.delete(user.id)
}
}

const userCache = new UserCache()

const { DataTypes, Model } = sequelize

Expand Down Expand Up @@ -206,14 +253,22 @@ class User extends Model {
*/
static async getUserByUsername(username) {
if (!username) return null
return this.findOne({

const cachedUser = userCache.getByUsername(username)
if (cachedUser) return cachedUser

const user = await this.findOne({
where: {
username: {
[sequelize.Op.like]: username
}
},
include: this.sequelize.models.mediaProgress
})

if (user) userCache.set(user)

return user
}

/**
Expand All @@ -223,14 +278,22 @@ class User extends Model {
*/
static async getUserByEmail(email) {
if (!email) return null
return this.findOne({

const cachedUser = userCache.getByEmail(email)
if (cachedUser) return cachedUser

const user = await this.findOne({
where: {
email: {
[sequelize.Op.like]: email
}
},
include: this.sequelize.models.mediaProgress
})

if (user) userCache.set(user)

return user
}

/**
Expand All @@ -240,9 +303,17 @@ class User extends Model {
*/
static async getUserById(userId) {
if (!userId) return null
return this.findByPk(userId, {

const cachedUser = userCache.getById(userId)
if (cachedUser) return cachedUser

const user = await this.findByPk(userId, {
include: this.sequelize.models.mediaProgress
})

if (user) userCache.set(user)

return user
}

/**
Expand All @@ -254,12 +325,19 @@ class User extends Model {
*/
static async getUserByIdOrOldId(userId) {
if (!userId) return null
return this.findOne({
const cachedUser = userCache.getById(userId) || userCache.getByOldId(userId)
if (cachedUser) return cachedUser

const user = await this.findOne({
where: {
[sequelize.Op.or]: [{ id: userId }, { 'extraData.oldUserId': userId }]
},
include: this.sequelize.models.mediaProgress
})

if (user) userCache.set(user)

return user
}

/**
Expand All @@ -269,10 +347,18 @@ class User extends Model {
*/
static async getUserByOpenIDSub(sub) {
if (!sub) return null
return this.findOne({

const cachedUser = userCache.getByOpenIDSub(sub)
if (cachedUser) return cachedUser

const user = await this.findOne({
where: sequelize.where(sequelize.literal(`extraData->>"authOpenIDSub"`), sub),
include: this.sequelize.models.mediaProgress
})

if (user) userCache.set(user)

return user
}

/**
Expand Down Expand Up @@ -623,6 +709,7 @@ class User extends Model {
mediaProgress = await this.sequelize.models.mediaProgress.create(newMediaProgressPayload)
this.mediaProgresses.push(mediaProgress)
}
userCache.maybeInvalidate(this)
return {
mediaProgress
}
Expand Down Expand Up @@ -804,6 +891,21 @@ class User extends Model {

return hasUpdates
}

async update(values, options) {
userCache.maybeInvalidate(this)
return await super.update(values, options)
}

async save(options) {
userCache.maybeInvalidate(this)
return await super.save(options)
}

async destroy(options) {
userCache.delete(this.id)
await super.destroy(options)
}
}

module.exports = User

0 comments on commit a382482

Please sign in to comment.