From cc9af86f350d6cce5fdd4eefcf59872a2e3f0b8c Mon Sep 17 00:00:00 2001 From: Sumit Ghosh Date: Thu, 14 Oct 2021 16:39:39 +0530 Subject: [PATCH] Included MigrateDbContext method in HostExtensions --- .../Catalog.API/Extensions/HostExtensions.cs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/Services/Catalog/Catalog.API/Extensions/HostExtensions.cs b/src/Services/Catalog/Catalog.API/Extensions/HostExtensions.cs index 44b7e3d87..8720fa809 100644 --- a/src/Services/Catalog/Catalog.API/Extensions/HostExtensions.cs +++ b/src/Services/Catalog/Catalog.API/Extensions/HostExtensions.cs @@ -61,6 +61,58 @@ public static class HostExtensions return host; } + public static IWebHost MigrateDbContext(this IWebHost host, Action seeder) where TContext : DbContext + { + var underK8s = host.IsInKubernetes(); + + using (var scope = host.Services.CreateScope()) + { + var services = scope.ServiceProvider; + + var logger = services.GetRequiredService>(); + + var context = services.GetService(); + + try + { + logger.LogInformation("Migrating database associated with context {DbContextName}", typeof(TContext).Name); + + if (underK8s) + { + InvokeSeeder(seeder, context, services); + } + else + { + var retry = Policy.Handle() + .WaitAndRetry(new TimeSpan[] + { + TimeSpan.FromSeconds(3), + TimeSpan.FromSeconds(5), + TimeSpan.FromSeconds(8), + }); + + //if the sql server container is not created on run docker compose this + //migration can't fail for network related exception. The retry options for DbContext only + //apply to transient exceptions + // Note that this is NOT applied when running some orchestrators (let the orchestrator to recreate the failing service) + retry.Execute(() => InvokeSeeder(seeder, context, services)); + } + + logger.LogInformation("Migrated database associated with context {DbContextName}", typeof(TContext).Name); + } + catch (Exception ex) + { + logger.LogError(ex, "An error occurred while migrating the database used on context {DbContextName}", typeof(TContext).Name); + if (underK8s) + { + throw; // Rethrow under k8s because we rely on k8s to re-run the pod + } + } + } + + return host; + } + private static void InvokeSeeder(Action seeder, TContext context, IServiceProvider services) where TContext : DbContext {