| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- using Application.Abstractions.Cache;
- using StackExchange.Redis;
- using System.Text.Json;
- namespace Infrastructure.Cache;
- public sealed class RedisCacheService(IConnectionMultiplexer redis) : ICacheService
- {
- private readonly IDatabase _db = redis.GetDatabase();
- private static readonly JsonSerializerOptions _jsonOptions = new()
- {
- PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
- WriteIndented = false
- };
- public async Task<T?> GetAsync<T>(string key, CancellationToken ct = default)
- {
- var value = await _db.StringGetAsync(key);
- if (value.IsNullOrEmpty)
- {
- return default;
- }
- return JsonSerializer.Deserialize<T>((string)value!, _jsonOptions);
- }
- public async Task SetAsync<T>(string key, T value, CancellationToken ct = default)
- {
- await _db.StringSetAsync(key, JsonSerializer.Serialize(value, _jsonOptions));
- }
- public async Task SetAsync<T>(string key, T value, TimeSpan expiry, CancellationToken ct = default)
- {
- await _db.StringSetAsync(key, JsonSerializer.Serialize(value, _jsonOptions), expiry);
- }
- public async Task RemoveAsync(string key, CancellationToken ct = default)
- {
- await _db.KeyDeleteAsync(key);
- }
- public async Task RemoveByPrefixAsync(string prefix, CancellationToken ct = default)
- {
- // SCAN 기반 비블로킹 스캔. KEYS 명령은 운영 Redis 에서 단일 스레드 블로킹이라 절대 금지
- var server = redis.GetServer(_db.Multiplexer.GetEndPoints().First());
- var batch = new List<RedisKey>(256);
- await foreach (var key in server.KeysAsync(database: _db.Database, pattern: $"{prefix}*", pageSize: 1000).WithCancellation(ct))
- {
- batch.Add(key);
- if (batch.Count >= 500)
- {
- await _db.KeyDeleteAsync(batch.ToArray());
- batch.Clear();
- }
- }
- if (batch.Count > 0)
- {
- await _db.KeyDeleteAsync(batch.ToArray());
- }
- }
- public async Task<bool> TryLockAsync(string key, TimeSpan expiry, CancellationToken ct = default)
- {
- return await _db.StringSetAsync(key, "1", expiry, When.NotExists);
- }
- }
|