How to run EFCore Migrate on ASP.NET start up WITH retries?

440 views Asked by At

So I want to run EF migrations when the Azure app service is first started. The following code works correctly:

public class Program
{
    public static void Main(string[] args)
    {
        ...
        var host = CreateHostBuilder(args).Build();
        using (var scope = host.Services.CreateScope())
        using (var context = scope.ServiceProvider.GetService<MyContext>())
        {
             context.Database.Migrate();
        }
        host.Run();
        ...
     }
 }

However because the database is running as a serverless instance on Azure, if it is currently paused, then it needs to retry (as the first connection attempt(s) fail).

Once the service is started, for requests I have configured retries using EnableRetryOnFailure - which works as expected:

services.AddDbContext<MyContext>(options =>
    {
        options.UseSqlServer(Configuration["...."],
           sqlServerOptionsAction: sqlOptions =>
           {
               sqlOptions.EnableRetryOnFailure(
                   maxRetryCount: 5,
                   maxRetryDelay: TimeSpan.FromSeconds(5),
                   errorNumbersToAdd: null);
           });
    });

So is there something similar I can use in Program.Main() to handle app service start Migrations?

Many thanks in advance!

1

There are 1 answers

1
Stelios Giakoumidis On BEST ANSWER

One way to solve this problem is to use Polly

You can create a policy like:

    var migrateDbPolicy = Policy
        .Handle<Exception>()
        .WaitAndRetry(4, retryAttempt => TimeSpan.FromSeconds(retryAttempt));

    migrateDbPolicy.Execute(() =>
    {
        context.Database.Migrate();
    });

So any code running into the execute method would be retried if the exception you have set in the policy is caught.

Polly is a very powerful library trusted by Microsoft. The example above is a very basic one. You can apply different policies on each type of exception (Generic Exception is not really suggested). You can have different waiting times etc.

I would suggest you spent some time and dig into it.