mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-01-18 05:12:51 +01:00
Avoid timeouts during EF migrations (#5937)
This commit is contained in:
parent
4e0423cb1e
commit
d3277306cf
@ -5,6 +5,7 @@ using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Npgsql;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Operations;
|
||||
|
||||
@ -21,7 +22,8 @@ namespace BTCPayServer.Abstractions.Contracts
|
||||
_migrationTableName = migrationTableName;
|
||||
}
|
||||
|
||||
public abstract T CreateContext();
|
||||
public T CreateContext() => CreateContext(null);
|
||||
public abstract T CreateContext(Action<NpgsqlDbContextOptionsBuilder> npgsqlOptionsAction = null);
|
||||
class CustomNpgsqlMigrationsSqlGenerator : NpgsqlMigrationsSqlGenerator
|
||||
{
|
||||
#pragma warning disable EF1001 // Internal EF Core API usage.
|
||||
@ -66,16 +68,18 @@ namespace BTCPayServer.Abstractions.Contracts
|
||||
}
|
||||
}
|
||||
|
||||
public void ConfigureBuilder(DbContextOptionsBuilder builder)
|
||||
public void ConfigureBuilder(DbContextOptionsBuilder builder) => ConfigureBuilder(builder, null);
|
||||
public void ConfigureBuilder(DbContextOptionsBuilder builder, Action<NpgsqlDbContextOptionsBuilder> npgsqlOptionsAction = null)
|
||||
{
|
||||
builder
|
||||
.UseNpgsql(_options.Value.ConnectionString, o =>
|
||||
{
|
||||
o.EnableRetryOnFailure(10);
|
||||
o.SetPostgresVersion(12, 0);
|
||||
var mainSearchPath = GetSearchPath(_options.Value.ConnectionString);
|
||||
var schemaPrefix = string.IsNullOrEmpty(_migrationTableName) ? "__EFMigrationsHistory" : _migrationTableName;
|
||||
o.MigrationsHistoryTable(schemaPrefix, mainSearchPath);
|
||||
npgsqlOptionsAction?.Invoke(o);
|
||||
var mainSearchPath = GetSearchPath(_options.Value.ConnectionString);
|
||||
var schemaPrefix = string.IsNullOrEmpty(_migrationTableName) ? "__EFMigrationsHistory" : _migrationTableName;
|
||||
o.MigrationsHistoryTable(schemaPrefix, mainSearchPath);
|
||||
})
|
||||
.ReplaceService<IMigrationsSqlGenerator, CustomNpgsqlMigrationsSqlGenerator>();
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using BTCPayServer.Abstractions.Contracts;
|
||||
using BTCPayServer.Abstractions.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
|
||||
|
||||
namespace BTCPayServer.Data
|
||||
{
|
||||
@ -14,11 +15,11 @@ namespace BTCPayServer.Data
|
||||
{
|
||||
}
|
||||
|
||||
public override ApplicationDbContext CreateContext()
|
||||
public override ApplicationDbContext CreateContext(Action<NpgsqlDbContextOptionsBuilder> npgsqlOptionsAction = null)
|
||||
{
|
||||
var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
|
||||
builder.AddInterceptors(Data.InvoiceData.MigrationInterceptor.Instance);
|
||||
ConfigureBuilder(builder);
|
||||
ConfigureBuilder(builder, npgsqlOptionsAction);
|
||||
return new ApplicationDbContext(builder.Options);
|
||||
}
|
||||
}
|
||||
|
@ -885,21 +885,25 @@ WHERE cte.""Id""=p.""Id""
|
||||
|
||||
private async Task Migrate(CancellationToken cancellationToken)
|
||||
{
|
||||
using (CancellationTokenSource timeout = new CancellationTokenSource(10_000))
|
||||
int cancellationTimeout = 60 * 60 * 24;
|
||||
using (CancellationTokenSource timeout = new CancellationTokenSource(cancellationTimeout))
|
||||
using (CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, cancellationToken))
|
||||
{
|
||||
retry:
|
||||
try
|
||||
{
|
||||
var db = _DBContextFactory.CreateContext();
|
||||
await db.Database.MigrateAsync();
|
||||
_logger.LogInformation("Running the migration scripts...");
|
||||
var db = _DBContextFactory.CreateContext(o => o.CommandTimeout(cancellationTimeout + 1));
|
||||
await db.Database.MigrateAsync(timeout.Token);
|
||||
_logger.LogInformation("All migration scripts ran successfully");
|
||||
}
|
||||
// Starting up
|
||||
catch (ConfigException) { throw; }
|
||||
catch when (!cts.Token.IsCancellationRequested)
|
||||
catch (Exception ex) when (!cts.Token.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogWarning(ex, "Error while running migration scripts, retrying...");
|
||||
await Task.Delay(1000, cts.Token);
|
||||
}
|
||||
catch { }
|
||||
|
Loading…
Reference in New Issue
Block a user