Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<MicrosoftPackageVersion Condition="'$(TargetFramework)' == 'net7.0'">7.*</MicrosoftPackageVersion>
<MicrosoftPackageVersion Condition="'$(TargetFramework)' == 'net8.0'">8.*</MicrosoftPackageVersion>
<MicrosoftPackageVersion Condition="'$(TargetFramework)' == 'net9.0'">9.*</MicrosoftPackageVersion>
<MicrosoftPackageVersion Condition="'$(TargetFramework)' == 'net10.0'">10.0.0-preview.*</MicrosoftPackageVersion>
<MicrosoftPackageVersion Condition="'$(TargetFramework)' == 'net10.0'">10.*</MicrosoftPackageVersion>
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title indicates "feat: add redis connect callback", but this PR also includes numerous package version updates (Aliyun SDK, EFCore providers, DistributedLock packages, etc.) and StackExchange.Redis API compatibility changes (RedisChannel wrapper). These changes appear unrelated to the redis connection callback feature. Consider either updating the PR title to reflect all changes, or splitting these changes into separate PRs for better maintainability and easier review.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignore


<BenchmarkDotNetPackageVersion>0.13.1</BenchmarkDotNetPackageVersion>
<MSTestPackageVersion>2.2.3</MSTestPackageVersion>
Expand All @@ -16,13 +16,13 @@
<MapsterPackageVersion>7.3.0</MapsterPackageVersion>
<DaprPackageVersion>1.10.0</DaprPackageVersion>
<GoogleProtobufPackageVersion>3.19.1</GoogleProtobufPackageVersion>
<MedallionDistributedLockPackageVersion>1.0.4</MedallionDistributedLockPackageVersion>
<MedallionDistributedLockPackageVersion>1.0.*</MedallionDistributedLockPackageVersion>
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change to MedallionDistributedLockPackageVersion from a fixed version (1.0.4) to a floating range (1.0.*) introduces supply chain risk because future builds will automatically consume any new 1.0.x release without explicit review. If an attacker compromises the package publisher or distribution channel, a malicious 1.0.x version could be pulled into your builds and run with access to your application's secrets and data. Prefer pinning this dependency to a specific, vetted version and updating it deliberately as part of a controlled dependency management process.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignore

<FluentValidationPackageVersion>11.1.0</FluentValidationPackageVersion>
<FluentValidationAspNetCorePackageVersion>11.1.2</FluentValidationAspNetCorePackageVersion>
<StackExchangeRedisPackageVersion>2.8.41</StackExchangeRedisPackageVersion>
<NESTPackageVersion>7.17.4</NESTPackageVersion>
<IdentityPackageVersion>7.5.0</IdentityPackageVersion>
<IdentityModelPackageVersion>6.0.0</IdentityModelPackageVersion>
<NewtonsoftJsonVersion>13.0.3</NewtonsoftJsonVersion>

<PackageId>$(AssemblyName)</PackageId>
<PackageIcon>packageIcon.png</PackageIcon>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static List<IsolationConfigurationOptions<TComponentConfig>> GetComponent
var configuration = serviceProvider.GetService<IMasaConfiguration>()?.Local ?? serviceProvider.GetService<IConfiguration>();
MasaArgumentException.ThrowIfNull(configuration);
return configuration
.GetSection(rootSectionName)
.GetSection(rootSectionName!)
.GetSection(sectionName)
.Get<List<IsolationConfigurationOptions<TComponentConfig>>>() ?? new();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,11 @@ namespace Masa.BuildingBlocks.Caching;

public static class DistributedCacheBuilderExtensions
{
/// <summary>
/// Add distributed Redis cache
/// </summary>
/// <param name="distributedCacheBuilder"></param>
/// <param name="redisSectionName">redis node name, not required, default: RedisConfig(Use local configuration)</param>
/// <param name="jsonSerializerOptions"></param>
/// <returns></returns>
public static void UseStackExchangeRedisCache(
this DistributedCacheBuilder distributedCacheBuilder,
string redisSectionName = RedisConstant.DEFAULT_REDIS_SECTION_NAME,
JsonSerializerOptions? jsonSerializerOptions = null)
JsonSerializerOptions? jsonSerializerOptions = null,
Action<IConnectionMultiplexer>? connectConfig = null)
{
distributedCacheBuilder.Services.AddConfigure<RedisConfigurationOptions>(redisSectionName, distributedCacheBuilder.Name);

Expand All @@ -41,14 +35,16 @@ public static void UseStackExchangeRedisCache(
redisConfigurationOptions,
serviceProvider.GetService<IFormatCacheKeyProvider>(),
jsonSerializerOptions,
serviceProvider.GetRequiredService<ITypeAliasFactory>().Create(distributedCacheBuilder.Name));
serviceProvider.GetRequiredService<ITypeAliasFactory>().Create(distributedCacheBuilder.Name),
connectConfig);
});
}

public static void UseStackExchangeRedisCache(
this DistributedCacheBuilder distributedCacheBuilder,
Action<RedisConfigurationOptions> action,
JsonSerializerOptions? jsonSerializerOptions = null)
JsonSerializerOptions? jsonSerializerOptions = null,
Action<IConnectionMultiplexer>? connectConfig = null)
{
distributedCacheBuilder.UseCustomDistributedCache(serviceProvider =>
{
Expand All @@ -58,7 +54,8 @@ public static void UseStackExchangeRedisCache(
redisConfigurationOptions,
serviceProvider.GetService<IFormatCacheKeyProvider>(),
jsonSerializerOptions,
serviceProvider.GetRequiredService<ITypeAliasFactory>().Create(distributedCacheBuilder.Name)
serviceProvider.GetRequiredService<ITypeAliasFactory>().Create(distributedCacheBuilder.Name),
connectConfig
);
return distributedCacheClient;
});
Expand All @@ -67,15 +64,17 @@ public static void UseStackExchangeRedisCache(
public static void UseStackExchangeRedisCache(
this DistributedCacheBuilder distributedCacheBuilder,
RedisConfigurationOptions redisConfigurationOptions,
JsonSerializerOptions? jsonSerializerOptions = null)
JsonSerializerOptions? jsonSerializerOptions = null,
Action<IConnectionMultiplexer>? connectConfig = null)
{
distributedCacheBuilder.UseCustomDistributedCache(serviceProvider =>
{
var distributedCacheClient = new RedisCacheClient(
redisConfigurationOptions,
serviceProvider.GetService<IFormatCacheKeyProvider>(),
jsonSerializerOptions,
serviceProvider.GetRequiredService<ITypeAliasFactory>().Create(distributedCacheBuilder.Name)
serviceProvider.GetRequiredService<ITypeAliasFactory>().Create(distributedCacheBuilder.Name),
connectConfig
);
return distributedCacheClient;
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) MASA Stack All rights reserved.
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

// ReSharper disable once CheckNamespace
Expand Down Expand Up @@ -29,7 +29,7 @@ public static HashEntry[] ConvertToHashEntries(
if (compressMode == CompressMode.None)
return (T?)Convert.ChangeType(redisValue, actualType);

var byteValue = (byte[])redisValue;
var byteValue = (byte[])redisValue!;
if (byteValue.Length == 0)
return default;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) MASA Stack All rights reserved.
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

// ReSharper disable once CheckNamespace
Expand Down Expand Up @@ -86,7 +86,7 @@ public static implicit operator ConfigurationOptions(RedisConfigurationOptions o
AbortOnConnectFail = options.AbortOnConnectFail,
AllowAdmin = options.AllowAdmin,
AsyncTimeout = options.AsyncTimeout,
ChannelPrefix = options.ChannelPrefix,
ChannelPrefix = new RedisChannel(options.ChannelPrefix, RedisChannel.PatternMode.Auto),
ClientName = options.ClientName,
ConnectRetry = options.ConnectRetry,
ConnectTimeout = options.ConnectTimeout,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ public RedisCacheClient(
RedisConfigurationOptions redisConfigurationOptions,
IFormatCacheKeyProvider? formatCacheKeyProvider = null,
JsonSerializerOptions? jsonSerializerOptions = null,
ITypeAliasProvider? typeAliasProvider = null)
: base(redisConfigurationOptions, jsonSerializerOptions)
ITypeAliasProvider? typeAliasProvider = null,
Action<IConnectionMultiplexer>? connectConfig = null)
: base(redisConfigurationOptions, jsonSerializerOptions, connectConfig)
{
_formatCacheKeyProvider = formatCacheKeyProvider ?? new DefaultFormatCacheKeyProvider();
_typeAliasProvider = typeAliasProvider;
Expand Down Expand Up @@ -95,7 +96,7 @@ private async Task<List<DataCacheModel<T>>> GetListAsync<T>(List<string> keys)
return GetAndRefresh(formatCacheKey, () =>
{
var cacheEntry = setter();
if (cacheEntry.Value == null)
if (EqualityComparer<T>.Default.Equals(cacheEntry.Value, default(T)))
return default;

SetCoreAsync(key, cacheEntry.Value, cacheEntry.CacheOptions).ConfigureAwait(false).GetAwaiter().GetResult();
Expand All @@ -117,7 +118,7 @@ private async Task<List<DataCacheModel<T>>> GetListAsync<T>(List<string> keys)
return await GetAndRefreshAsync(key, async () =>
{
var cacheEntry = await setter().ConfigureAwait(false);
if (cacheEntry.Value == null)
if (EqualityComparer<T>.Default.Equals(cacheEntry.Value, default(T)))
return default;

await SetCoreAsync(key, cacheEntry.Value, cacheEntry.CacheOptions).ConfigureAwait(false);
Expand All @@ -137,7 +138,8 @@ public override IEnumerable<string> GetKeys(string keyPattern)
{
pattern = keyPattern
});
return (string[])cacheResult;
if (cacheResult == null) return Array.Empty<string>();
return (string[])cacheResult!;
}

public override IEnumerable<string> GetKeys<T>(
Expand All @@ -160,7 +162,8 @@ public override async Task<IEnumerable<string>> GetKeysAsync(string keyPattern)
{
pattern = keyPattern
}).ConfigureAwait(false);
return (string[])cacheResult;
if (cacheResult == null) return Array.Empty<string>();
return (string[])cacheResult!;
}

public override Task<IEnumerable<string>> GetKeysAsync<T>(
Expand Down Expand Up @@ -371,21 +374,21 @@ public override void Publish(string channel, Action<PublishOptions> options)
{
var publishOptions = GetAndCheckPublishOptions(channel, options);
var message = JsonSerializer.Serialize(publishOptions, GlobalJsonSerializerOptions);
Subscriber.Publish(channel, message);
Subscriber.Publish(new RedisChannel(channel, RedisChannel.PatternMode.Auto), message);
}

public override async Task PublishAsync(string channel, Action<PublishOptions> options)
{
var publishOptions = GetAndCheckPublishOptions(channel, options);
var message = JsonSerializer.Serialize(publishOptions, GlobalJsonSerializerOptions);
await Subscriber.PublishAsync(channel, message).ConfigureAwait(false);
await Subscriber.PublishAsync(new RedisChannel(channel, RedisChannel.PatternMode.Auto), message).ConfigureAwait(false);
}

public override void Subscribe<T>(string channel, Action<SubscribeOptions<T>> options)
{
Subscriber.Subscribe(channel, (_, message) =>
Subscriber.Subscribe(new RedisChannel(channel, RedisChannel.PatternMode.Auto), (_, message) =>
{
var subscribeOptions = JsonSerializer.Deserialize<SubscribeOptions<T>>(message);
var subscribeOptions = JsonSerializer.Deserialize<SubscribeOptions<T>>(message.ToString());
if (subscribeOptions != null)
subscribeOptions.IsPublisherClient = subscribeOptions.UniquelyIdentifies == UniquelyIdentifies;
options(subscribeOptions!);
Expand All @@ -394,9 +397,9 @@ public override void Subscribe<T>(string channel, Action<SubscribeOptions<T>> op

public override Task SubscribeAsync<T>(string channel, Action<SubscribeOptions<T>> options)
{
return Subscriber.SubscribeAsync(channel, (_, message) =>
return Subscriber.SubscribeAsync(new RedisChannel(channel, RedisChannel.PatternMode.Auto), (_, message) =>
{
var subscribeOptions = JsonSerializer.Deserialize<SubscribeOptions<T>>(message);
var subscribeOptions = JsonSerializer.Deserialize<SubscribeOptions<T>>(message.ToString());
if (subscribeOptions != null)
subscribeOptions.IsPublisherClient = subscribeOptions.UniquelyIdentifies == UniquelyIdentifies;
options(subscribeOptions!);
Expand All @@ -405,12 +408,12 @@ public override Task SubscribeAsync<T>(string channel, Action<SubscribeOptions<T

public override void UnSubscribe<T>(string channel)
{
Subscriber.Unsubscribe(channel);
Subscriber.Unsubscribe(new RedisChannel(channel, RedisChannel.PatternMode.Auto));
}

public override Task UnSubscribeAsync<T>(string channel)
{
return Subscriber.UnsubscribeAsync(channel);
return Subscriber.UnsubscribeAsync(new RedisChannel(channel, RedisChannel.PatternMode.Auto));
}

#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,25 @@ protected IDatabase Db
}
}

private IConnectionMultiplexer _connection;
private ConnectionMultiplexer _connection;
protected readonly JsonSerializerOptions GlobalJsonSerializerOptions;
private readonly CacheEntryOptions _globalCacheEntryOptions;
private readonly CacheOptions _globalCacheOptions;

private readonly RedisConfigurationOptions _redisConfigurationOptions;
private readonly Action<IConnectionMultiplexer>? _connectConfig;

protected RedisCacheClientBase(
RedisConfigurationOptions redisConfigurationOptions,
JsonSerializerOptions? jsonSerializerOptions)
JsonSerializerOptions? jsonSerializerOptions,
Action<IConnectionMultiplexer>? connectConfig)
: this(redisConfigurationOptions.GlobalCacheOptions, redisConfigurationOptions, jsonSerializerOptions)
{
_redisConfigurationOptions = redisConfigurationOptions;
_connectConfig = connectConfig;
var redisConfiguration = redisConfigurationOptions.GetAvailableRedisOptions();
_connection = ConnectionMultiplexer.Connect(redisConfiguration);
Subscriber = _connection.GetSubscriber();
_connectConfig?.Invoke(_connection);
InstanceId = redisConfiguration.InstanceId;
}

Expand All @@ -60,6 +63,7 @@ protected void EnsureDbConnection()
// Attempt to reconnect
var redisConfiguration = _redisConfigurationOptions.GetAvailableRedisOptions();
_connection = ConnectionMultiplexer.Connect(redisConfiguration);
_connectConfig?.Invoke(_connection);
Subscriber = _connection.GetSubscriber();
}

Expand Down Expand Up @@ -161,7 +165,7 @@ private List<DataCacheModel> GetListCoreByKeyPattern(
List<DataCacheModel> list = new List<DataCacheModel>();
foreach (var redisResult in arrayRedisResult)
{
var byteArray = (RedisValue[])redisResult.Value;
var byteArray = (RedisValue[])redisResult.Value!;
list.Add(MapMetadataByAutomatic(redisResult.Key, byteArray));
}
return list;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ public static IMasaConfigurationBuilder UseDcc(
this IMasaConfigurationBuilder builder,
Action<JsonSerializerOptions>? jsonSerializerOptions = null,
Action<CallerBuilder>? callerBuilder = null,
string sectionName = "DccOptions")
string sectionName = "DccOptions",
Action<StackExchange.Redis.IConnectionMultiplexer>? connectConfig = null)
{
var configurationSection = builder.Configuration.GetSection(sectionName);
var dccOptions = configurationSection.Get<DccOptions>();
MasaArgumentException.ThrowIfNull(dccOptions);
return builder.UseDcc(dccOptions, jsonSerializerOptions, callerBuilder);
return builder.UseDcc(dccOptions, jsonSerializerOptions, callerBuilder, connectConfig);
}

public static IMasaConfigurationBuilder UseDcc(
this IMasaConfigurationBuilder builder,
DccOptions dccOptions,
Action<JsonSerializerOptions>? jsonSerializerOptions = null,
Action<CallerBuilder>? action = null)
Action<CallerBuilder>? action = null,
Action<StackExchange.Redis.IConnectionMultiplexer>? connectConfig = null)
{
var services = builder.Services;

Expand All @@ -37,7 +39,7 @@ public static IMasaConfigurationBuilder UseDcc(
services.AddSingleton<IDccConfigurationProvider, DccConfigurationProvider>();
services.AddMultilevelCache(
DEFAULT_CLIENT_NAME,
distributedCacheOptions => distributedCacheOptions.UseStackExchangeRedisCache(dccOptions.RedisOptions),
distributedCacheOptions => distributedCacheOptions.UseStackExchangeRedisCache(dccOptions.RedisOptions, connectConfig: connectConfig),
multilevelCacheOptions =>
{
multilevelCacheOptions.SubscribeKeyType = SubscribeKeyType.SpecificPrefix;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DistributedLock.Azure" Version="1.0.0" />
<PackageReference Include="DistributedLock.Azure" Version="$(MedallionDistributedLockPackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DistributedLock.FileSystem" Version="1.0.1" />
<PackageReference Include="DistributedLock.FileSystem" Version="$(MedallionDistributedLockPackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DistributedLock.MySql" Version="1.0.0" />
<PackageReference Include="DistributedLock.MySql" Version="$(MedallionDistributedLockPackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DistributedLock.Oracle" Version="1.0.0" />
<PackageReference Include="DistributedLock.Oracle" Version="$(MedallionDistributedLockPackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DistributedLock.Postgres" Version="1.0.2" />
<PackageReference Include="DistributedLock.Postgres" Version="$(MedallionDistributedLockPackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DistributedLock.Redis" Version="1.0.1" />
<PackageReference Include="DistributedLock.Redis" Version="$(MedallionDistributedLockPackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DistributedLock.SqlServer" Version="1.0.1" />
<PackageReference Include="DistributedLock.SqlServer" Version="$(MedallionDistributedLockPackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DistributedLock.WaitHandles" Version="1.0.0" />
<PackageReference Include="DistributedLock.WaitHandles" Version="$(MedallionDistributedLockPackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading
Loading