enhance(backend): improve userkeypair cache
This commit is contained in:
		
							parent
							
								
									cf6a302f8f
								
							
						
					
					
						commit
						28647de196
					
				packages/backend/src
|  | @ -40,7 +40,7 @@ import { TwoFactorAuthenticationService } from './TwoFactorAuthenticationService | ||||||
| import { UserBlockingService } from './UserBlockingService.js'; | import { UserBlockingService } from './UserBlockingService.js'; | ||||||
| import { CacheService } from './CacheService.js'; | import { CacheService } from './CacheService.js'; | ||||||
| import { UserFollowingService } from './UserFollowingService.js'; | import { UserFollowingService } from './UserFollowingService.js'; | ||||||
| import { UserKeypairStoreService } from './UserKeypairStoreService.js'; | import { UserKeypairService } from './UserKeypairService.js'; | ||||||
| import { UserListService } from './UserListService.js'; | import { UserListService } from './UserListService.js'; | ||||||
| import { UserMutingService } from './UserMutingService.js'; | import { UserMutingService } from './UserMutingService.js'; | ||||||
| import { UserSuspendService } from './UserSuspendService.js'; | import { UserSuspendService } from './UserSuspendService.js'; | ||||||
|  | @ -161,7 +161,7 @@ const $TwoFactorAuthenticationService: Provider = { provide: 'TwoFactorAuthentic | ||||||
| const $UserBlockingService: Provider = { provide: 'UserBlockingService', useExisting: UserBlockingService }; | const $UserBlockingService: Provider = { provide: 'UserBlockingService', useExisting: UserBlockingService }; | ||||||
| const $CacheService: Provider = { provide: 'CacheService', useExisting: CacheService }; | const $CacheService: Provider = { provide: 'CacheService', useExisting: CacheService }; | ||||||
| const $UserFollowingService: Provider = { provide: 'UserFollowingService', useExisting: UserFollowingService }; | const $UserFollowingService: Provider = { provide: 'UserFollowingService', useExisting: UserFollowingService }; | ||||||
| const $UserKeypairStoreService: Provider = { provide: 'UserKeypairStoreService', useExisting: UserKeypairStoreService }; | const $UserKeypairService: Provider = { provide: 'UserKeypairService', useExisting: UserKeypairService }; | ||||||
| const $UserListService: Provider = { provide: 'UserListService', useExisting: UserListService }; | const $UserListService: Provider = { provide: 'UserListService', useExisting: UserListService }; | ||||||
| const $UserMutingService: Provider = { provide: 'UserMutingService', useExisting: UserMutingService }; | const $UserMutingService: Provider = { provide: 'UserMutingService', useExisting: UserMutingService }; | ||||||
| const $UserSuspendService: Provider = { provide: 'UserSuspendService', useExisting: UserSuspendService }; | const $UserSuspendService: Provider = { provide: 'UserSuspendService', useExisting: UserSuspendService }; | ||||||
|  | @ -284,7 +284,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||||
| 		UserBlockingService, | 		UserBlockingService, | ||||||
| 		CacheService, | 		CacheService, | ||||||
| 		UserFollowingService, | 		UserFollowingService, | ||||||
| 		UserKeypairStoreService, | 		UserKeypairService, | ||||||
| 		UserListService, | 		UserListService, | ||||||
| 		UserMutingService, | 		UserMutingService, | ||||||
| 		UserSuspendService, | 		UserSuspendService, | ||||||
|  | @ -401,7 +401,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||||
| 		$UserBlockingService, | 		$UserBlockingService, | ||||||
| 		$CacheService, | 		$CacheService, | ||||||
| 		$UserFollowingService, | 		$UserFollowingService, | ||||||
| 		$UserKeypairStoreService, | 		$UserKeypairService, | ||||||
| 		$UserListService, | 		$UserListService, | ||||||
| 		$UserMutingService, | 		$UserMutingService, | ||||||
| 		$UserSuspendService, | 		$UserSuspendService, | ||||||
|  | @ -519,7 +519,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||||
| 		UserBlockingService, | 		UserBlockingService, | ||||||
| 		CacheService, | 		CacheService, | ||||||
| 		UserFollowingService, | 		UserFollowingService, | ||||||
| 		UserKeypairStoreService, | 		UserKeypairService, | ||||||
| 		UserListService, | 		UserListService, | ||||||
| 		UserMutingService, | 		UserMutingService, | ||||||
| 		UserSuspendService, | 		UserSuspendService, | ||||||
|  | @ -635,7 +635,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting | ||||||
| 		$UserBlockingService, | 		$UserBlockingService, | ||||||
| 		$CacheService, | 		$CacheService, | ||||||
| 		$UserFollowingService, | 		$UserFollowingService, | ||||||
| 		$UserKeypairStoreService, | 		$UserKeypairService, | ||||||
| 		$UserListService, | 		$UserListService, | ||||||
| 		$UserMutingService, | 		$UserMutingService, | ||||||
| 		$UserSuspendService, | 		$UserSuspendService, | ||||||
|  |  | ||||||
|  | @ -1,24 +1,34 @@ | ||||||
| import { Inject, Injectable } from '@nestjs/common'; | import { Inject, Injectable } from '@nestjs/common'; | ||||||
|  | import Redis from 'ioredis'; | ||||||
| import type { User } from '@/models/entities/User.js'; | import type { User } from '@/models/entities/User.js'; | ||||||
| import type { UserKeypairsRepository } from '@/models/index.js'; | import type { UserKeypairsRepository } from '@/models/index.js'; | ||||||
| import { MemoryKVCache } from '@/misc/cache.js'; | import { RedisKVCache } from '@/misc/cache.js'; | ||||||
| import type { UserKeypair } from '@/models/entities/UserKeypair.js'; | import type { UserKeypair } from '@/models/entities/UserKeypair.js'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import { bindThis } from '@/decorators.js'; | import { bindThis } from '@/decorators.js'; | ||||||
| 
 | 
 | ||||||
| @Injectable() | @Injectable() | ||||||
| export class UserKeypairStoreService { | export class UserKeypairService { | ||||||
| 	private cache: MemoryKVCache<UserKeypair>; | 	private cache: RedisKVCache<UserKeypair>; | ||||||
| 
 | 
 | ||||||
| 	constructor( | 	constructor( | ||||||
|  | 		@Inject(DI.redis) | ||||||
|  | 		private redisClient: Redis.Redis, | ||||||
|  | 
 | ||||||
| 		@Inject(DI.userKeypairsRepository) | 		@Inject(DI.userKeypairsRepository) | ||||||
| 		private userKeypairsRepository: UserKeypairsRepository, | 		private userKeypairsRepository: UserKeypairsRepository, | ||||||
| 	) { | 	) { | ||||||
| 		this.cache = new MemoryKVCache<UserKeypair>(Infinity); | 		this.cache = new RedisKVCache<UserKeypair>(this.redisClient, 'userKeypair', { | ||||||
|  | 			lifetime: 1000 * 60 * 60 * 24, // 24h
 | ||||||
|  | 			memoryCacheLifetime: Infinity, | ||||||
|  | 			fetcher: (key) => this.userKeypairsRepository.findOneByOrFail({ userId: key }), | ||||||
|  | 			toRedisConverter: (value) => JSON.stringify(value), | ||||||
|  | 			fromRedisConverter: (value) => JSON.parse(value), | ||||||
|  | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@bindThis | 	@bindThis | ||||||
| 	public async getUserKeypair(userId: User['id']): Promise<UserKeypair> { | 	public async getUserKeypair(userId: User['id']): Promise<UserKeypair> { | ||||||
| 		return await this.cache.fetch(userId, () => this.userKeypairsRepository.findOneByOrFail({ userId: userId })); | 		return await this.cache.fetch(userId); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ import type { NoteReaction } from '@/models/entities/NoteReaction.js'; | ||||||
| import type { Emoji } from '@/models/entities/Emoji.js'; | import type { Emoji } from '@/models/entities/Emoji.js'; | ||||||
| import type { Poll } from '@/models/entities/Poll.js'; | import type { Poll } from '@/models/entities/Poll.js'; | ||||||
| import type { PollVote } from '@/models/entities/PollVote.js'; | import type { PollVote } from '@/models/entities/PollVote.js'; | ||||||
| import { UserKeypairStoreService } from '@/core/UserKeypairStoreService.js'; | import { UserKeypairService } from '@/core/UserKeypairService.js'; | ||||||
| import { MfmService } from '@/core/MfmService.js'; | import { MfmService } from '@/core/MfmService.js'; | ||||||
| import { UserEntityService } from '@/core/entities/UserEntityService.js'; | import { UserEntityService } from '@/core/entities/UserEntityService.js'; | ||||||
| import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; | import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js'; | ||||||
|  | @ -53,7 +53,7 @@ export class ApRendererService { | ||||||
| 		private userEntityService: UserEntityService, | 		private userEntityService: UserEntityService, | ||||||
| 		private driveFileEntityService: DriveFileEntityService, | 		private driveFileEntityService: DriveFileEntityService, | ||||||
| 		private ldSignatureService: LdSignatureService, | 		private ldSignatureService: LdSignatureService, | ||||||
| 		private userKeypairStoreService: UserKeypairStoreService, | 		private userKeypairService: UserKeypairService, | ||||||
| 		private apMfmService: ApMfmService, | 		private apMfmService: ApMfmService, | ||||||
| 		private mfmService: MfmService, | 		private mfmService: MfmService, | ||||||
| 	) { | 	) { | ||||||
|  | @ -473,7 +473,7 @@ export class ApRendererService { | ||||||
| 			...hashtagTags, | 			...hashtagTags, | ||||||
| 		]; | 		]; | ||||||
| 
 | 
 | ||||||
| 		const keypair = await this.userKeypairStoreService.getUserKeypair(user.id); | 		const keypair = await this.userKeypairService.getUserKeypair(user.id); | ||||||
| 
 | 
 | ||||||
| 		const person = { | 		const person = { | ||||||
| 			type: isSystem ? 'Application' : user.isBot ? 'Service' : 'Person', | 			type: isSystem ? 'Application' : user.isBot ? 'Service' : 'Person', | ||||||
|  | @ -640,7 +640,7 @@ export class ApRendererService { | ||||||
| 
 | 
 | ||||||
| 	@bindThis | 	@bindThis | ||||||
| 	public async attachLdSignature(activity: any, user: { id: User['id']; host: null; }): Promise<IActivity> { | 	public async attachLdSignature(activity: any, user: { id: User['id']; host: null; }): Promise<IActivity> { | ||||||
| 		const keypair = await this.userKeypairStoreService.getUserKeypair(user.id); | 		const keypair = await this.userKeypairService.getUserKeypair(user.id); | ||||||
| 
 | 
 | ||||||
| 		const ldSignature = this.ldSignatureService.use(); | 		const ldSignature = this.ldSignatureService.use(); | ||||||
| 		ldSignature.debug = false; | 		ldSignature.debug = false; | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import { Inject, Injectable } from '@nestjs/common'; | ||||||
| import { DI } from '@/di-symbols.js'; | import { DI } from '@/di-symbols.js'; | ||||||
| import type { Config } from '@/config.js'; | import type { Config } from '@/config.js'; | ||||||
| import type { User } from '@/models/entities/User.js'; | import type { User } from '@/models/entities/User.js'; | ||||||
| import { UserKeypairStoreService } from '@/core/UserKeypairStoreService.js'; | import { UserKeypairService } from '@/core/UserKeypairService.js'; | ||||||
| import { HttpRequestService } from '@/core/HttpRequestService.js'; | import { HttpRequestService } from '@/core/HttpRequestService.js'; | ||||||
| import { LoggerService } from '@/core/LoggerService.js'; | import { LoggerService } from '@/core/LoggerService.js'; | ||||||
| import { bindThis } from '@/decorators.js'; | import { bindThis } from '@/decorators.js'; | ||||||
|  | @ -131,7 +131,7 @@ export class ApRequestService { | ||||||
| 		@Inject(DI.config) | 		@Inject(DI.config) | ||||||
| 		private config: Config, | 		private config: Config, | ||||||
| 
 | 
 | ||||||
| 		private userKeypairStoreService: UserKeypairStoreService, | 		private userKeypairService: UserKeypairService, | ||||||
| 		private httpRequestService: HttpRequestService, | 		private httpRequestService: HttpRequestService, | ||||||
| 		private loggerService: LoggerService, | 		private loggerService: LoggerService, | ||||||
| 	) { | 	) { | ||||||
|  | @ -143,7 +143,7 @@ export class ApRequestService { | ||||||
| 	public async signedPost(user: { id: User['id'] }, url: string, object: any) { | 	public async signedPost(user: { id: User['id'] }, url: string, object: any) { | ||||||
| 		const body = JSON.stringify(object); | 		const body = JSON.stringify(object); | ||||||
| 
 | 
 | ||||||
| 		const keypair = await this.userKeypairStoreService.getUserKeypair(user.id); | 		const keypair = await this.userKeypairService.getUserKeypair(user.id); | ||||||
| 
 | 
 | ||||||
| 		const req = ApRequestCreator.createSignedPost({ | 		const req = ApRequestCreator.createSignedPost({ | ||||||
| 			key: { | 			key: { | ||||||
|  | @ -170,7 +170,7 @@ export class ApRequestService { | ||||||
| 	 */ | 	 */ | ||||||
| 	@bindThis | 	@bindThis | ||||||
| 	public async signedGet(url: string, user: { id: User['id'] }) { | 	public async signedGet(url: string, user: { id: User['id'] }) { | ||||||
| 		const keypair = await this.userKeypairStoreService.getUserKeypair(user.id); | 		const keypair = await this.userKeypairService.getUserKeypair(user.id); | ||||||
| 
 | 
 | ||||||
| 		const req = ApRequestCreator.createSignedGet({ | 		const req = ApRequestCreator.createSignedGet({ | ||||||
| 			key: { | 			key: { | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ import type { Config } from '@/config.js'; | ||||||
| import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; | import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; | ||||||
| import { QueueService } from '@/core/QueueService.js'; | import { QueueService } from '@/core/QueueService.js'; | ||||||
| import type { LocalUser, User } from '@/models/entities/User.js'; | import type { LocalUser, User } from '@/models/entities/User.js'; | ||||||
| import { UserKeypairStoreService } from '@/core/UserKeypairStoreService.js'; | import { UserKeypairService } from '@/core/UserKeypairService.js'; | ||||||
| import type { Following } from '@/models/entities/Following.js'; | import type { Following } from '@/models/entities/Following.js'; | ||||||
| import { countIf } from '@/misc/prelude/array.js'; | import { countIf } from '@/misc/prelude/array.js'; | ||||||
| import type { Note } from '@/models/entities/Note.js'; | import type { Note } from '@/models/entities/Note.js'; | ||||||
|  | @ -58,7 +58,7 @@ export class ActivityPubServerService { | ||||||
| 		private userEntityService: UserEntityService, | 		private userEntityService: UserEntityService, | ||||||
| 		private apRendererService: ApRendererService, | 		private apRendererService: ApRendererService, | ||||||
| 		private queueService: QueueService, | 		private queueService: QueueService, | ||||||
| 		private userKeypairStoreService: UserKeypairStoreService, | 		private userKeypairService: UserKeypairService, | ||||||
| 		private queryService: QueryService, | 		private queryService: QueryService, | ||||||
| 	) { | 	) { | ||||||
| 		//this.createServer = this.createServer.bind(this);
 | 		//this.createServer = this.createServer.bind(this);
 | ||||||
|  | @ -540,7 +540,7 @@ export class ActivityPubServerService { | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			const keypair = await this.userKeypairStoreService.getUserKeypair(user.id); | 			const keypair = await this.userKeypairService.getUserKeypair(user.id); | ||||||
| 
 | 
 | ||||||
| 			if (this.userEntityService.isLocalUser(user)) { | 			if (this.userEntityService.isLocalUser(user)) { | ||||||
| 				reply.header('Cache-Control', 'public, max-age=180'); | 				reply.header('Cache-Control', 'public, max-age=180'); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue