130
CHAPTER 5 | Designing and Developing Multi-Container and Microservice-Based .NET Applications
There’s an important caveat when applying
migrations and seeding a
database during container
startup. Since the database server might not be available for whatever reason, you must handle retries
while waiting for the server to be available. This retry
logic is handled by the
MigrateDbContext()
extension method, as shown in the following code:
public
static
IWebHost MigrateDbContext
(
this
IWebHost host,
ActionIServiceProvider> 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}"
,
Dostları ilə paylaş: