diff --git a/Directory.Packages.props b/Directory.Packages.props index 8ad14c0c4b2..2ac3d4504d6 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -91,6 +91,7 @@ + diff --git a/src/Components/Aspire.Pomelo.EntityFrameworkCore.MySql/Aspire.Pomelo.EntityFrameworkCore.MySql.csproj b/src/Components/Aspire.Pomelo.EntityFrameworkCore.MySql/Aspire.Pomelo.EntityFrameworkCore.MySql.csproj index 1f22963aa53..29a4cf42224 100644 --- a/src/Components/Aspire.Pomelo.EntityFrameworkCore.MySql/Aspire.Pomelo.EntityFrameworkCore.MySql.csproj +++ b/src/Components/Aspire.Pomelo.EntityFrameworkCore.MySql/Aspire.Pomelo.EntityFrameworkCore.MySql.csproj @@ -19,6 +19,7 @@ + diff --git a/src/Components/Aspire.Pomelo.EntityFrameworkCore.MySql/AspireEFMySqlExtensions.cs b/src/Components/Aspire.Pomelo.EntityFrameworkCore.MySql/AspireEFMySqlExtensions.cs index 695acaebadd..74ebe77be4e 100644 --- a/src/Components/Aspire.Pomelo.EntityFrameworkCore.MySql/AspireEFMySqlExtensions.cs +++ b/src/Components/Aspire.Pomelo.EntityFrameworkCore.MySql/AspireEFMySqlExtensions.cs @@ -8,8 +8,12 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using MySqlConnector; using MySqlConnector.Logging; using OpenTelemetry.Metrics; +using Polly; +using Polly.Registry; +using Polly.Retry; using Pomelo.EntityFrameworkCore.MySql.Infrastructure.Internal; namespace Microsoft.Extensions.Hosting; @@ -65,6 +69,22 @@ public static partial class AspireEFMySqlExtensions builder.Services.AddDbContextPool(ConfigureDbContext); + const string resilienceKey = "Microsoft.Extensions.Hosting.AspireEFMySqlExtensions.ServerVersion"; + builder.Services.AddResiliencePipeline(resilienceKey, static builder => + { + // Values are taken from MySqlRetryingExecutionStrategy.MaxRetryCount and MaxRetryDelay. + builder.AddRetry(new RetryStrategyOptions + { + ShouldHandle = static args => args.Outcome is { Exception: MySqlException { IsTransient: true } } + ? PredicateResult.True() + : PredicateResult.False(), + BackoffType = DelayBackoffType.Exponential, + MaxRetryAttempts = 6, + Delay = TimeSpan.FromSeconds(1), + MaxDelay = TimeSpan.FromSeconds(30), + }); + }); + ConfigureInstrumentation(builder, settings); void ConfigureDbContext(IServiceProvider serviceProvider, DbContextOptionsBuilder dbContextOptionsBuilder) @@ -81,7 +101,10 @@ void ConfigureDbContext(IServiceProvider serviceProvider, DbContextOptionsBuilde if (settings.ServerVersion is null) { ConnectionStringValidation.ValidateConnectionString(settings.ConnectionString, connectionName, DefaultConfigSectionName, $"{DefaultConfigSectionName}:{typeof(TContext).Name}", isEfDesignTime: EF.IsDesignTime); - serverVersion = ServerVersion.AutoDetect(connectionString); + + var resiliencePipelineProvider = serviceProvider.GetRequiredService>(); + var resiliencePipeline = resiliencePipelineProvider.GetPipeline(resilienceKey); + serverVersion = resiliencePipeline.Execute(static cs => ServerVersion.AutoDetect(cs), connectionString); } else {