mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Add in-memory user cache
This commit is contained in:
		
							parent
							
								
									2e970cbb39
								
							
						
					
					
						commit
						a382482173
					
				| @ -990,28 +990,18 @@ class Auth { | ||||
|         }) | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     Database.userModel | ||||
|       .update( | ||||
|         { | ||||
|           pash: pw | ||||
|         }, | ||||
|         { | ||||
|           where: { id: matchingUser.id } | ||||
|         } | ||||
|       ) | ||||
|       .then(() => { | ||||
|     try { | ||||
|       await matchingUser.update({ pash: pw }) | ||||
|       Logger.info(`[Auth] User "${matchingUser.username}" changed password`) | ||||
|       res.json({ | ||||
|         success: true | ||||
|       }) | ||||
|       }) | ||||
|       .catch((error) => { | ||||
|     } catch (error) { | ||||
|       Logger.error(`[Auth] User "${matchingUser.username}" failed to change password`, error) | ||||
|       res.json({ | ||||
|         error: 'Unknown error' | ||||
|       }) | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
| @ -206,7 +253,11 @@ 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 | ||||
| @ -214,6 +265,10 @@ class User extends Model { | ||||
|       }, | ||||
|       include: this.sequelize.models.mediaProgress | ||||
|     }) | ||||
| 
 | ||||
|     if (user) userCache.set(user) | ||||
| 
 | ||||
|     return user | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -223,7 +278,11 @@ 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 | ||||
| @ -231,6 +290,10 @@ class User extends Model { | ||||
|       }, | ||||
|       include: this.sequelize.models.mediaProgress | ||||
|     }) | ||||
| 
 | ||||
|     if (user) userCache.set(user) | ||||
| 
 | ||||
|     return user | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -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 | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -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 | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -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 | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
| @ -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 | ||||
|     } | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user