-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathRedisInfrastructureService.cs
More file actions
101 lines (80 loc) · 3.2 KB
/
RedisInfrastructureService.cs
File metadata and controls
101 lines (80 loc) · 3.2 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
using ByteSync.ServerCommon.Business.Repositories;
using ByteSync.ServerCommon.Business.Settings;
using ByteSync.ServerCommon.Entities;
using ByteSync.ServerCommon.Exceptions;
using ByteSync.ServerCommon.Interfaces.Factories;
using ByteSync.ServerCommon.Interfaces.Services;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RedLockNet;
using RedLockNet.SERedis;
using RedLockNet.SERedis.Configuration;
using StackExchange.Redis;
namespace ByteSync.ServerCommon.Services;
public class RedisInfrastructureService : IRedisInfrastructureService
{
private readonly RedisSettings _redisSettings;
private readonly ICacheKeyFactory _cacheKeyFactory;
private readonly RedLockFactory _redLockFactory;
private static string? _cachedConnectionString;
private readonly ConnectionMultiplexer _connectionMultiplexer;
public RedisInfrastructureService(IOptions<RedisSettings> redisSettings, ICacheKeyFactory cacheKeyFactory, ILoggerFactory loggerFactory)
{
_redisSettings = redisSettings.Value;
_cacheKeyFactory = cacheKeyFactory;
_cachedConnectionString ??= _redisSettings.ConnectionString;
_connectionMultiplexer = _lazyMultiplexer.Value;
var multiplexers = new List<RedLockMultiplexer>
{
_connectionMultiplexer,
};
RedLockRetryConfiguration redLockRetryConfiguration = new RedLockRetryConfiguration(5, 500);
_redLockFactory = RedLockFactory.Create(multiplexers, redLockRetryConfiguration, loggerFactory);
}
private static readonly Lazy<ConnectionMultiplexer> _lazyMultiplexer = new(() =>
{
var options = ConfigurationOptions.Parse(_cachedConnectionString!);
options.Ssl = true;
options.AbortOnConnectFail = false;
if (options.ConnectTimeout < 10000)
{
options.ConnectTimeout = 10000;
}
return ConnectionMultiplexer.Connect(options);
});
public ITransaction OpenTransaction()
{
return _connectionMultiplexer.GetDatabase().CreateTransaction();
}
public IDatabaseAsync GetDatabase()
{
return _connectionMultiplexer.GetDatabase();
}
public IDatabaseAsync GetDatabase(ITransaction? transaction)
{
IDatabaseAsync database = transaction != null ? transaction : GetDatabase();
return database;
}
public async Task<IRedLock> AcquireLockAsync(EntityType entityType, string entityId)
{
var cacheKey = ComputeCacheKey(entityType, entityId);
return await AcquireLockAsync(cacheKey);
}
public async Task<IRedLock> AcquireLockAsync(CacheKey cacheKey)
{
var redisLock = await _redLockFactory.CreateLockAsync(cacheKey.Value, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(1));
if (redisLock.IsAcquired)
{
return redisLock;
}
else
{
throw new AcquireRedisLockException(cacheKey.Value, redisLock);
}
}
public CacheKey ComputeCacheKey(EntityType entityType, string entityId)
{
CacheKey cacheKey = _cacheKeyFactory.Create(entityType, entityId);
return cacheKey;
}
}