resid pt 3: friendship checks & auth session reads
This commit is contained in:
23
src/common/cache/cache-keys.ts
vendored
23
src/common/cache/cache-keys.ts
vendored
@@ -4,6 +4,8 @@ export const CACHE_NAMESPACE = {
|
||||
FRIENDS_LIST: 'friends-list',
|
||||
DOLLS_LIST: 'dolls-list',
|
||||
USERS_SEARCH: 'users-search',
|
||||
FRIENDSHIP_CHECK: 'friendship-check',
|
||||
AUTH_SESSION: 'auth-session',
|
||||
} as const;
|
||||
|
||||
function normalizeKeyPart(value: string | undefined): string {
|
||||
@@ -18,6 +20,8 @@ export const CACHE_TTL_SECONDS = {
|
||||
FRIENDS_LIST: 30,
|
||||
DOLLS_LIST: 30,
|
||||
USERS_SEARCH: 20,
|
||||
FRIENDSHIP_CHECK: 120,
|
||||
AUTH_SESSION: 30,
|
||||
} as const;
|
||||
|
||||
export function friendsListCacheKey(userId: string): string {
|
||||
@@ -56,6 +60,25 @@ export function usersSearchCacheKey(
|
||||
|
||||
export const USERS_SEARCH_GLOBAL_TAG = 'global';
|
||||
|
||||
export function friendshipCheckCacheKey(
|
||||
userId: string,
|
||||
friendId: string,
|
||||
): string {
|
||||
return `${normalizeKeyPart(userId)}:${normalizeKeyPart(friendId)}`;
|
||||
}
|
||||
|
||||
export function friendshipCheckUserTag(userId: string): string {
|
||||
return `user:${normalizeKeyPart(userId)}`;
|
||||
}
|
||||
|
||||
export function authSessionCacheKey(sessionId: string): string {
|
||||
return normalizeKeyPart(sessionId);
|
||||
}
|
||||
|
||||
export function authSessionUserTag(userId: string): string {
|
||||
return `user:${normalizeKeyPart(userId)}`;
|
||||
}
|
||||
|
||||
export function usersSearchUserTag(userId: string): string {
|
||||
return `user:${normalizeKeyPart(userId)}`;
|
||||
}
|
||||
|
||||
42
src/common/cache/cache-tags.service.ts
vendored
42
src/common/cache/cache-tags.service.ts
vendored
@@ -1,11 +1,24 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { CacheService } from './cache.service';
|
||||
import { parsePositiveInteger } from '../config/env.utils';
|
||||
|
||||
const CACHE_TAG_SET_TTL_SECONDS = 86_400;
|
||||
const DEFAULT_CACHE_TAG_MAX_ENTRIES = 5_000;
|
||||
|
||||
@Injectable()
|
||||
export class CacheTagsService {
|
||||
constructor(private readonly cacheService: CacheService) {}
|
||||
private readonly cacheTagMaxEntries: number;
|
||||
|
||||
constructor(
|
||||
private readonly cacheService: CacheService,
|
||||
private readonly configService: ConfigService,
|
||||
) {
|
||||
this.cacheTagMaxEntries = parsePositiveInteger(
|
||||
this.configService.get<string>('CACHE_TAG_MAX_ENTRIES'),
|
||||
DEFAULT_CACHE_TAG_MAX_ENTRIES,
|
||||
);
|
||||
}
|
||||
|
||||
async rememberKeyForTag(
|
||||
namespace: string,
|
||||
@@ -28,6 +41,11 @@ export class CacheTagsService {
|
||||
redisClient.sadd(tagSetKey, keyWithNamespace),
|
||||
redisClient.expire(tagSetKey, CACHE_TAG_SET_TTL_SECONDS),
|
||||
]);
|
||||
|
||||
const size = await redisClient.scard(tagSetKey);
|
||||
if (size > this.cacheTagMaxEntries) {
|
||||
await this.trimTagSet(tagSetKey, size - this.cacheTagMaxEntries);
|
||||
}
|
||||
} catch (error) {
|
||||
this.cacheService.recordError('tag remember', tagSetKey, error);
|
||||
}
|
||||
@@ -63,4 +81,26 @@ export class CacheTagsService {
|
||||
`${namespace}:${tag}`,
|
||||
);
|
||||
}
|
||||
|
||||
private async trimTagSet(
|
||||
tagSetKey: string,
|
||||
countToDrop: number,
|
||||
): Promise<void> {
|
||||
const redisClient = this.cacheService.getRedisClient();
|
||||
if (!redisClient || countToDrop <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const sample = await redisClient.srandmember(tagSetKey, countToDrop);
|
||||
const members = Array.isArray(sample) ? sample : [sample].filter(Boolean);
|
||||
if (members.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
await redisClient.srem(tagSetKey, ...members);
|
||||
} catch (error) {
|
||||
this.cacheService.recordError('tag trim', tagSetKey, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
src/common/cache/index.ts
vendored
1
src/common/cache/index.ts
vendored
@@ -1,3 +1,4 @@
|
||||
export { CacheModule } from './cache.module';
|
||||
export { CacheService } from './cache.service';
|
||||
export { CacheTagsService } from './cache-tags.service';
|
||||
export { RedisThrottlerStorage } from './redis-throttler.storage';
|
||||
|
||||
Reference in New Issue
Block a user