forked from NpgsqlRest/NpgsqlRest
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRedisCache.cs
More file actions
123 lines (110 loc) · 3.86 KB
/
Copy pathRedisCache.cs
File metadata and controls
123 lines (110 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using Microsoft.Extensions.Logging;
using NpgsqlRest;
using StackExchange.Redis;
namespace NpgsqlRestClient
{
public class RedisCache : IRoutineCache, IDisposable
{
private readonly ConnectionMultiplexer _redis;
private readonly IDatabase _db;
private readonly ILogger? _logger;
private bool _disposed;
public RedisCache(string configuration, ILogger? logger = null)
{
_logger = logger;
ConnectionMultiplexer? redis = null;
try
{
_logger?.LogDebug("Connecting to Redis with configuration: {RedisConfiguration}", configuration);
redis = ConnectionMultiplexer.Connect(configuration);
_db = redis.GetDatabase();
// Test the connection
_db.Ping();
_redis = redis; // Only assign after successful initialization
_logger?.LogInformation("Successfully connected to Redis cache");
}
catch (Exception ex)
{
// Dispose the connection if initialization failed
redis?.Dispose();
_disposed = true;
_logger?.LogError(ex, "Failed to initialize Redis connection");
throw new InvalidOperationException("Failed to initialize Redis cache", ex);
}
}
public bool Get(RoutineEndpoint endpoint, string key, out object? result)
{
result = null;
if (_disposed)
{
_logger?.LogWarning("Attempted to get from disposed Redis cache");
return false;
}
try
{
var redisValue = _db.StringGet(key);
if (redisValue.HasValue)
{
result = redisValue.ToString();
_logger?.LogTrace("Cache hit for key: {Key}", key);
return true;
}
_logger?.LogTrace("Cache miss for key: {Key}", key);
return false;
}
catch (RedisException ex)
{
_logger?.LogError(ex, "Redis error while getting key: {Key}", key);
return false;
}
catch (Exception ex)
{
_logger?.LogError(ex, "Unexpected error while getting key from Redis: {Key}", key);
return false;
}
}
public void AddOrUpdate(RoutineEndpoint endpoint, string key, object? value)
{
if (_disposed)
{
_logger?.LogWarning("Attempted to set on disposed Redis cache");
return;
}
try
{
var stringValue = value?.ToString();
var expiry = endpoint.CacheExpiresIn;
_db.StringSet(key, stringValue, expiry);
_logger?.LogTrace("Cached value for key: {Key} with expiry: {Expiry}", key, expiry);
}
catch (RedisException ex)
{
_logger?.LogError(ex, "Redis error while setting key: {Key}", key);
}
catch (Exception ex)
{
_logger?.LogError(ex, "Unexpected error while setting key in Redis: {Key}", key);
}
}
public void Dispose()
{
if (_disposed)
{
return;
}
try
{
_redis.Dispose();
_logger?.LogInformation("Redis cache connection disposed");
}
catch (Exception ex)
{
_logger?.LogError(ex, "Error while disposing Redis cache connection");
}
finally
{
_disposed = true;
}
}
}
}