merge: Remove infinite caches to prevent memory leak (!587)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/587

Closes #600 and #601

Approved-by: Amelia Yukii <amelia.yukii@shourai.de>
Approved-by: Marie <marie@kaifa.ch>
This commit is contained in:
dakkar 2024-08-06 16:51:18 +00:00
commit 4e7df7a5f2
12 changed files with 94 additions and 87 deletions

View file

@ -26,7 +26,7 @@ const parseEmojiStrRegexp = /^([-\w]+)(?:@([\w.-]+))?$/;
@Injectable()
export class CustomEmojiService implements OnApplicationShutdown {
private cache: MemoryKVCache<MiEmoji | null>;
private emojisCache: MemoryKVCache<MiEmoji | null>;
public localEmojisCache: RedisSingleCache<Map<string, MiEmoji>>;
constructor(
@ -49,7 +49,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
private globalEventService: GlobalEventService,
private driveService: DriveService,
) {
this.cache = new MemoryKVCache<MiEmoji | null>(1000 * 60 * 60 * 12);
this.emojisCache = new MemoryKVCache<MiEmoji | null>(1000 * 60 * 60 * 12); // 12h
this.localEmojisCache = new RedisSingleCache<Map<string, MiEmoji>>(this.redisClient, 'localEmojis', {
lifetime: 1000 * 60 * 30, // 30m
@ -357,14 +357,14 @@ export class CustomEmojiService implements OnApplicationShutdown {
if (name == null) return null;
if (host == null) return null;
const newHost = host === this.config.host ? null : host;
const newHost = host === this.config.host ? null : host;
const queryOrNull = async () => (await this.emojisRepository.findOneBy({
name,
host: newHost ?? IsNull(),
})) ?? null;
const emoji = await this.cache.fetch(`${name} ${host}`, queryOrNull);
const emoji = await this.emojisCache.fetch(`${name} ${host}`, queryOrNull);
if (emoji == null) return null;
return emoji.publicUrl || emoji.originalUrl; // || emoji.originalUrl してるのは後方互換性のためpublicUrlはstringなので??はだめ)
@ -391,7 +391,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
*/
@bindThis
public async prefetchEmojis(emojis: { name: string; host: string | null; }[]): Promise<void> {
const notCachedEmojis = emojis.filter(emoji => this.cache.get(`${emoji.name} ${emoji.host}`) == null);
const notCachedEmojis = emojis.filter(emoji => this.emojisCache.get(`${emoji.name} ${emoji.host}`) == null);
const emojisQuery: any[] = [];
const hosts = new Set(notCachedEmojis.map(e => e.host));
for (const host of hosts) {
@ -406,7 +406,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
select: ['name', 'host', 'originalUrl', 'publicUrl'],
}) : [];
for (const emoji of _emojis) {
this.cache.set(`${emoji.name} ${emoji.host}`, emoji);
this.emojisCache.set(`${emoji.name} ${emoji.host}`, emoji);
}
}
@ -431,7 +431,7 @@ export class CustomEmojiService implements OnApplicationShutdown {
@bindThis
public dispose(): void {
this.cache.dispose();
this.emojisCache.dispose();
}
@bindThis