mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-03 09:29:10 +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()
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
_Host.Start();
|
||||
_Host.StartWithTasksAsync().GetAwaiter().GetResult();
|
||||
|
||||
var urls = _Host.ServerFeatures.Get<IServerAddressesFeature>().Addresses;
|
||||
foreach (var url in urls)
|
||||
|
|
|
@ -34,11 +34,29 @@ using BTCPayServer.Data;
|
|||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using NBXplorer.DerivationStrategy;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace BTCPayServer
|
||||
{
|
||||
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)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
|
|
@ -78,6 +78,7 @@ namespace BTCPayServer.Hosting
|
|||
services.TryAddSingleton<InvoicePaymentNotification>();
|
||||
services.TryAddSingleton<BTCPayServerOptions>(o =>
|
||||
o.GetRequiredService<IOptions<BTCPayServerOptions>>().Value);
|
||||
services.AddStartupTask<MigrationStartupTask>();
|
||||
services.TryAddSingleton<InvoiceRepository>(o =>
|
||||
{
|
||||
var opts = o.GetRequiredService<BTCPayServerOptions>();
|
||||
|
@ -184,7 +185,6 @@ namespace BTCPayServer.Hosting
|
|||
o.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(DerivationStrategyBase)));
|
||||
});
|
||||
services.AddSingleton<IHostedService, CssThemeManagerHostedService>();
|
||||
services.AddSingleton<IHostedService, MigratorHostedService>();
|
||||
|
||||
services.AddSingleton<IHostedService, HostedServices.CheckConfigurationHostedService>();
|
||||
|
||||
|
@ -316,37 +316,9 @@ namespace BTCPayServer.Hosting
|
|||
|
||||
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>();
|
||||
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.Stores;
|
||||
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 StoreRepository _StoreRepository;
|
||||
private BTCPayNetworkProvider _NetworkProvider;
|
||||
private SettingsRepository _Settings;
|
||||
public MigratorHostedService(
|
||||
public MigrationStartupTask(
|
||||
BTCPayNetworkProvider networkProvider,
|
||||
StoreRepository storeRepository,
|
||||
ApplicationDbContextFactory dbContextFactory,
|
||||
|
@ -28,18 +30,11 @@ namespace BTCPayServer.HostedServices
|
|||
_NetworkProvider = networkProvider;
|
||||
_Settings = settingsRepository;
|
||||
}
|
||||
internal override Task[] InitializeTasks()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
Update()
|
||||
};
|
||||
}
|
||||
|
||||
private async Task Update()
|
||||
public async Task ExecuteAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Migrate(cancellationToken);
|
||||
var settings = (await _Settings.GetSettingAsync<MigrationSettings>()) ?? new MigrationSettings();
|
||||
if (!settings.DeprecatedLightningConnectionStringCheck)
|
||||
{
|
||||
|
@ -80,11 +75,34 @@ namespace BTCPayServer.HostedServices
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logs.PayServer.LogError(ex, "Error on the MigratorHostedService");
|
||||
Logs.PayServer.LogError(ex, "Error on the MigrationStartupTask");
|
||||
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()
|
||||
{
|
||||
bool save = false;
|
|
@ -68,7 +68,7 @@ namespace BTCPayServer
|
|||
})
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
host.StartAsync().GetAwaiter().GetResult();
|
||||
host.StartWithTasksAsync().GetAwaiter().GetResult();
|
||||
var urls = host.ServerFeatures.Get<IServerAddressesFeature>().Addresses;
|
||||
foreach (var url in urls)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue