mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-03 17:36:59 +01:00
Use Migration startup task when starting BTCPay instead of hosted service.
This commit is contained in:
parent
3c4455c23c
commit
36046f08f7
6 changed files with 65 additions and 44 deletions
|
@ -148,7 +148,7 @@ namespace BTCPayServer.Tests
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
.UseStartup<Startup>()
|
.UseStartup<Startup>()
|
||||||
.Build();
|
.Build();
|
||||||
_Host.Start();
|
_Host.StartWithTasksAsync().GetAwaiter().GetResult();
|
||||||
|
|
||||||
var urls = _Host.ServerFeatures.Get<IServerAddressesFeature>().Addresses;
|
var urls = _Host.ServerFeatures.Get<IServerAddressesFeature>().Addresses;
|
||||||
foreach (var url in urls)
|
foreach (var url in urls)
|
||||||
|
|
|
@ -34,11 +34,29 @@ using BTCPayServer.Data;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using NBXplorer.DerivationStrategy;
|
using NBXplorer.DerivationStrategy;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
|
||||||
namespace BTCPayServer
|
namespace BTCPayServer
|
||||||
{
|
{
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
|
public static IServiceCollection AddStartupTask<T>(this IServiceCollection services)
|
||||||
|
where T : class, IStartupTask
|
||||||
|
=> services.AddTransient<IStartupTask, T>();
|
||||||
|
public static async Task StartWithTasksAsync(this IWebHost webHost, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
// Load all tasks from DI
|
||||||
|
var startupTasks = webHost.Services.GetServices<IStartupTask>();
|
||||||
|
|
||||||
|
// Execute all the tasks
|
||||||
|
foreach (var startupTask in startupTasks)
|
||||||
|
{
|
||||||
|
await startupTask.ExecuteAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the tasks as normal
|
||||||
|
await webHost.StartAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
public static string PrettyPrint(this TimeSpan expiration)
|
public static string PrettyPrint(this TimeSpan expiration)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
|
@ -78,6 +78,7 @@ namespace BTCPayServer.Hosting
|
||||||
services.TryAddSingleton<InvoicePaymentNotification>();
|
services.TryAddSingleton<InvoicePaymentNotification>();
|
||||||
services.TryAddSingleton<BTCPayServerOptions>(o =>
|
services.TryAddSingleton<BTCPayServerOptions>(o =>
|
||||||
o.GetRequiredService<IOptions<BTCPayServerOptions>>().Value);
|
o.GetRequiredService<IOptions<BTCPayServerOptions>>().Value);
|
||||||
|
services.AddStartupTask<MigrationStartupTask>();
|
||||||
services.TryAddSingleton<InvoiceRepository>(o =>
|
services.TryAddSingleton<InvoiceRepository>(o =>
|
||||||
{
|
{
|
||||||
var opts = o.GetRequiredService<BTCPayServerOptions>();
|
var opts = o.GetRequiredService<BTCPayServerOptions>();
|
||||||
|
@ -184,7 +185,6 @@ namespace BTCPayServer.Hosting
|
||||||
o.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(DerivationStrategyBase)));
|
o.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(DerivationStrategyBase)));
|
||||||
});
|
});
|
||||||
services.AddSingleton<IHostedService, CssThemeManagerHostedService>();
|
services.AddSingleton<IHostedService, CssThemeManagerHostedService>();
|
||||||
services.AddSingleton<IHostedService, MigratorHostedService>();
|
|
||||||
|
|
||||||
services.AddSingleton<IHostedService, HostedServices.CheckConfigurationHostedService>();
|
services.AddSingleton<IHostedService, HostedServices.CheckConfigurationHostedService>();
|
||||||
|
|
||||||
|
@ -316,37 +316,9 @@ namespace BTCPayServer.Hosting
|
||||||
|
|
||||||
public static IApplicationBuilder UsePayServer(this IApplicationBuilder app)
|
public static IApplicationBuilder UsePayServer(this IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
|
|
||||||
{
|
|
||||||
//Wait the DB is ready
|
|
||||||
Retry(() =>
|
|
||||||
{
|
|
||||||
scope.ServiceProvider.GetRequiredService<ApplicationDbContext>().Database.Migrate();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
app.UseMiddleware<BTCPayMiddleware>();
|
app.UseMiddleware<BTCPayMiddleware>();
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Retry(Action act)
|
|
||||||
{
|
|
||||||
CancellationTokenSource cts = new CancellationTokenSource(1000);
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
act();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Starting up
|
|
||||||
catch (PostgresException ex) when (ex.SqlState == "57P03") { Thread.Sleep(1000); }
|
|
||||||
catch when (!cts.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
Thread.Sleep(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
13
BTCPayServer/IStartupTask.cs
Normal file
13
BTCPayServer/IStartupTask.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BTCPayServer
|
||||||
|
{
|
||||||
|
public interface IStartupTask
|
||||||
|
{
|
||||||
|
Task ExecuteAsync(CancellationToken cancellationToken = default);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,16 +8,18 @@ using BTCPayServer.Data;
|
||||||
using BTCPayServer.Services;
|
using BTCPayServer.Services;
|
||||||
using BTCPayServer.Services.Stores;
|
using BTCPayServer.Services.Stores;
|
||||||
using BTCPayServer.Logging;
|
using BTCPayServer.Logging;
|
||||||
|
using System.Threading;
|
||||||
|
using Npgsql;
|
||||||
|
|
||||||
namespace BTCPayServer.HostedServices
|
namespace BTCPayServer
|
||||||
{
|
{
|
||||||
public class MigratorHostedService : BaseAsyncService
|
public class MigrationStartupTask : IStartupTask
|
||||||
{
|
{
|
||||||
private ApplicationDbContextFactory _DBContextFactory;
|
private ApplicationDbContextFactory _DBContextFactory;
|
||||||
private StoreRepository _StoreRepository;
|
private StoreRepository _StoreRepository;
|
||||||
private BTCPayNetworkProvider _NetworkProvider;
|
private BTCPayNetworkProvider _NetworkProvider;
|
||||||
private SettingsRepository _Settings;
|
private SettingsRepository _Settings;
|
||||||
public MigratorHostedService(
|
public MigrationStartupTask(
|
||||||
BTCPayNetworkProvider networkProvider,
|
BTCPayNetworkProvider networkProvider,
|
||||||
StoreRepository storeRepository,
|
StoreRepository storeRepository,
|
||||||
ApplicationDbContextFactory dbContextFactory,
|
ApplicationDbContextFactory dbContextFactory,
|
||||||
|
@ -28,18 +30,11 @@ namespace BTCPayServer.HostedServices
|
||||||
_NetworkProvider = networkProvider;
|
_NetworkProvider = networkProvider;
|
||||||
_Settings = settingsRepository;
|
_Settings = settingsRepository;
|
||||||
}
|
}
|
||||||
internal override Task[] InitializeTasks()
|
public async Task ExecuteAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
|
||||||
return new[]
|
|
||||||
{
|
|
||||||
Update()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Update()
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
await Migrate(cancellationToken);
|
||||||
var settings = (await _Settings.GetSettingAsync<MigrationSettings>()) ?? new MigrationSettings();
|
var settings = (await _Settings.GetSettingAsync<MigrationSettings>()) ?? new MigrationSettings();
|
||||||
if (!settings.DeprecatedLightningConnectionStringCheck)
|
if (!settings.DeprecatedLightningConnectionStringCheck)
|
||||||
{
|
{
|
||||||
|
@ -80,11 +75,34 @@ namespace BTCPayServer.HostedServices
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logs.PayServer.LogError(ex, "Error on the MigratorHostedService");
|
Logs.PayServer.LogError(ex, "Error on the MigrationStartupTask");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task Migrate(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
using (CancellationTokenSource timeout = new CancellationTokenSource(10_000))
|
||||||
|
using (CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, cancellationToken))
|
||||||
|
{
|
||||||
|
retry:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _DBContextFactory.CreateContext().Database.MigrateAsync();
|
||||||
|
}
|
||||||
|
// Starting up
|
||||||
|
catch when (!cts.Token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Task.Delay(1000, cts.Token);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ConvertConvertWalletKeyPathRoots()
|
private async Task ConvertConvertWalletKeyPathRoots()
|
||||||
{
|
{
|
||||||
bool save = false;
|
bool save = false;
|
|
@ -68,7 +68,7 @@ namespace BTCPayServer
|
||||||
})
|
})
|
||||||
.UseStartup<Startup>()
|
.UseStartup<Startup>()
|
||||||
.Build();
|
.Build();
|
||||||
host.StartAsync().GetAwaiter().GetResult();
|
host.StartWithTasksAsync().GetAwaiter().GetResult();
|
||||||
var urls = host.ServerFeatures.Get<IServerAddressesFeature>().Addresses;
|
var urls = host.ServerFeatures.Get<IServerAddressesFeature>().Addresses;
|
||||||
foreach (var url in urls)
|
foreach (var url in urls)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue