using Bit.Core.Utilities; using Microsoft.Data.SqlClient; namespace Bit.Admin.HostedServices; public class DatabaseMigrationHostedService : IHostedService, IDisposable { private readonly ILogger _logger; private readonly IDbMigrator _dbMigrator; public DatabaseMigrationHostedService( IDbMigrator dbMigrator, ILogger logger) { _logger = logger; _dbMigrator = dbMigrator; } public virtual async Task StartAsync(CancellationToken cancellationToken) { // Wait 20 seconds to allow database to come online await Task.Delay(20000); var maxMigrationAttempts = 10; for (var i = 1; i <= maxMigrationAttempts; i++) { try { _dbMigrator.MigrateDatabase(true, cancellationToken); // TODO: Maybe flip a flag somewhere to indicate migration is complete?? break; } catch (SqlException e) { if (i >= maxMigrationAttempts) { _logger.LogError(e, "Database failed to migrate."); throw; } else { _logger.LogError(e, "Database unavailable for migration. Trying again (attempt #{0})...", i + 1); await Task.Delay(20000); } } } } public virtual Task StopAsync(CancellationToken cancellationToken) { return Task.FromResult(0); } public virtual void Dispose() { } }