SPMS_API/SPMS.Infrastructure/Caching/RedisConnection.cs

71 lines
1.9 KiB
C#

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SPMS.Application.Settings;
using StackExchange.Redis;
namespace SPMS.Infrastructure.Caching;
public class RedisConnection : IAsyncDisposable
{
private readonly RedisSettings _settings;
private readonly ILogger<RedisConnection> _logger;
private readonly SemaphoreSlim _semaphore = new(1, 1);
private ConnectionMultiplexer? _connection;
public RedisConnection(IOptions<RedisSettings> settings, ILogger<RedisConnection> logger)
{
_settings = settings.Value;
_logger = logger;
}
public async Task<IDatabase> GetDatabaseAsync()
{
if (_connection is { IsConnected: true })
return _connection.GetDatabase();
await _semaphore.WaitAsync();
try
{
if (_connection is { IsConnected: true })
return _connection.GetDatabase();
_connection?.Dispose();
_logger.LogInformation("Redis 연결 시도: {ConnectionString}",
MaskConnectionString(_settings.ConnectionString));
_connection = await ConnectionMultiplexer.ConnectAsync(_settings.ConnectionString);
_logger.LogInformation("Redis 연결 성공");
return _connection.GetDatabase();
}
catch (Exception ex)
{
_logger.LogError(ex, "Redis 연결 실패");
throw;
}
finally
{
_semaphore.Release();
}
}
private static string MaskConnectionString(string connectionString)
{
var parts = connectionString.Split(',');
return parts.Length > 0 ? parts[0] + ",..." : connectionString;
}
public async ValueTask DisposeAsync()
{
if (_connection != null)
{
await _connection.CloseAsync();
_connection.Dispose();
}
_semaphore.Dispose();
GC.SuppressFinalize(this);
}
}