From 909765d60427c57c7c2c135b7b0aa47600ea1db0 Mon Sep 17 00:00:00 2001 From: wzh425 Date: Wed, 30 Oct 2024 16:20:39 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E2=99=BB=20refactor(IDistributedCache):=20?= =?UTF-8?q?Optimize=20connections=20under=20Isolation=20and=20Attempt=20to?= =?UTF-8?q?=20reconnect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Directory.Build.props | 2 +- .../Internal/DistributedCacheClientCache.cs | 24 +++++++++++++ .../ServiceCollectionExtensions.Core.cs | 5 ++- .../RedisCacheClientBase.cs | 34 +++++++++++++++---- 4 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/DistributedCacheClientCache.cs diff --git a/Directory.Build.props b/Directory.Build.props index 4ac25d396..efdc90fbf 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - net6.0;net7.0;net8.0 + net6.0 6.0.0 7.0.0 8.0.0 diff --git a/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/DistributedCacheClientCache.cs b/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/DistributedCacheClientCache.cs new file mode 100644 index 000000000..2908c026c --- /dev/null +++ b/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/DistributedCacheClientCache.cs @@ -0,0 +1,24 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.BuildingBlocks.Caching; + +internal class DistributedCacheClientCache +{ + public static ConcurrentDictionary CacheClients { get; set; } = new(); + + public IManualDistributedCacheClient GetCacheClient(IServiceProvider serviceProvider) + { + var multiEnvironmentContext = serviceProvider.GetRequiredService(); + var environment = multiEnvironmentContext.CurrentEnvironment; + + if (CacheClients.TryGetValue(environment, out var cachedClient)) + { + return cachedClient; + } + + var cacheClient = serviceProvider.GetRequiredService>().Service; + CacheClients[environment] = cacheClient; + return cacheClient; + } +} diff --git a/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/ServiceCollectionExtensions.Core.cs b/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/ServiceCollectionExtensions.Core.cs index 67ed3f85b..25c475013 100644 --- a/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/ServiceCollectionExtensions.Core.cs +++ b/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/ServiceCollectionExtensions.Core.cs @@ -23,8 +23,9 @@ public static void TryAddDistributedCache( services.TryAddTransient(serviceProvider => { var cacheClient = serviceProvider.EnableIsolation() ? - serviceProvider.GetRequiredService>().Service : + serviceProvider.GetRequiredService().GetCacheClient(serviceProvider) : serviceProvider.GetRequiredService>().Service; + return new DefaultDistributedCacheClient(cacheClient); }); services.TryAddTransient(serviceProvider @@ -65,6 +66,8 @@ private static void AddTypeAlias( private static void AddCaching(this IServiceCollection services) { + services.TryAddSingleton(); + services.TryAddSingleton>(serviceProvider => new SingletonService(serviceProvider.GetRequiredService() .Create())); diff --git a/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/RedisCacheClientBase.cs b/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/RedisCacheClientBase.cs index 20cf755e2..39d8272a5 100644 --- a/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/RedisCacheClientBase.cs +++ b/src/Contrib/Caching/Distributed/Masa.Contrib.Caching.Distributed.StackExchangeRedis/RedisCacheClientBase.cs @@ -7,29 +7,29 @@ public abstract class RedisCacheClientBase : DistributedCacheClientBase { protected readonly string? InstanceId; protected static readonly Guid UniquelyIdentifies = Guid.NewGuid(); - protected readonly ISubscriber Subscriber; + protected ISubscriber Subscriber; protected IDatabase Db { get { - if (_connection.IsConnected || _connection.IsConnecting) - return _connection.GetDatabase(); - - throw new NotSupportedException("Redis service has been disconnected, please wait for reconnection and try again"); + return EnsureDbConnection(); } } - private readonly IConnectionMultiplexer _connection; + private IConnectionMultiplexer _connection; protected readonly JsonSerializerOptions GlobalJsonSerializerOptions; private readonly CacheEntryOptions _globalCacheEntryOptions; private readonly CacheOptions _globalCacheOptions; + private readonly RedisConfigurationOptions _redisConfigurationOptions; + protected RedisCacheClientBase( RedisConfigurationOptions redisConfigurationOptions, JsonSerializerOptions? jsonSerializerOptions) : this(redisConfigurationOptions.GlobalCacheOptions, redisConfigurationOptions, jsonSerializerOptions) { + _redisConfigurationOptions = redisConfigurationOptions; var redisConfiguration = redisConfigurationOptions.GetAvailableRedisOptions(); _connection = ConnectionMultiplexer.Connect(redisConfiguration); Subscriber = _connection.GetSubscriber(); @@ -51,6 +51,28 @@ private RedisCacheClientBase( GlobalJsonSerializerOptions = jsonSerializerOptions ?? new JsonSerializerOptions().EnableDynamicTypes(); } + protected IDatabase EnsureDbConnection() + { + if (_connection.IsConnected || _connection.IsConnecting) + { + return _connection.GetDatabase(); + } + + // Attempt to reconnect + var redisConfiguration = _redisConfigurationOptions.GetAvailableRedisOptions(); + _connection = ConnectionMultiplexer.Connect(redisConfiguration); + Subscriber = _connection.GetSubscriber(); + + if (_connection.IsConnected || _connection.IsConnecting) + { + return _connection.GetDatabase(); + } + else + { + throw new NotSupportedException("Unable to reconnect to Redis, please check the connection settings and try again."); + } + } + protected T? ConvertToValue(RedisValue value, out bool isExist) { if (value is { HasValue: true, IsNullOrEmpty: false }) From f689242015a7132214e4bcbe1a8a6c9fe41ac449 Mon Sep 17 00:00:00 2001 From: wzh425 Date: Wed, 30 Oct 2024 16:21:41 +0800 Subject: [PATCH 2/4] chore: TargetFrameworks --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index efdc90fbf..4ac25d396 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - net6.0 + net6.0;net7.0;net8.0 6.0.0 7.0.0 8.0.0 From 3a938ab20c3ec5389f3fb9ea517862f3817d6fe7 Mon Sep 17 00:00:00 2001 From: wzh425 Date: Wed, 30 Oct 2024 17:19:47 +0800 Subject: [PATCH 3/4] refactor: Code optimization --- Directory.Build.props | 2 +- .../Internal/DistributedCacheClientCache.cs | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 4ac25d396..efdc90fbf 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - net6.0;net7.0;net8.0 + net6.0 6.0.0 7.0.0 8.0.0 diff --git a/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/DistributedCacheClientCache.cs b/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/DistributedCacheClientCache.cs index 2908c026c..4b23a2efa 100644 --- a/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/DistributedCacheClientCache.cs +++ b/src/BuildingBlocks/Caching/Masa.BuildingBlocks.Caching/Internal/DistributedCacheClientCache.cs @@ -12,13 +12,10 @@ public IManualDistributedCacheClient GetCacheClient(IServiceProvider serviceProv var multiEnvironmentContext = serviceProvider.GetRequiredService(); var environment = multiEnvironmentContext.CurrentEnvironment; - if (CacheClients.TryGetValue(environment, out var cachedClient)) + return CacheClients.GetOrAdd(environment, env => { - return cachedClient; - } - - var cacheClient = serviceProvider.GetRequiredService>().Service; - CacheClients[environment] = cacheClient; - return cacheClient; + var cacheClient = serviceProvider.GetRequiredService>().Service; + return cacheClient; + }); } } From a25efeb362bbd0ad76e151b60c4c2b8e7e015f09 Mon Sep 17 00:00:00 2001 From: wzh425 Date: Wed, 30 Oct 2024 17:20:21 +0800 Subject: [PATCH 4/4] chore: TargetFrameworks --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index efdc90fbf..4ac25d396 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - net6.0 + net6.0;net7.0;net8.0 6.0.0 7.0.0 8.0.0