Compare commits

..

2 Commits

4 changed files with 150 additions and 1 deletions

View File

@ -0,0 +1,14 @@
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
namespace KonSoft.Admin.DbMigrations
{
public class AdminDataSeeder : IDataSeedContributor, ITransientDependency
{
public Task SeedAsync(DataSeedContext context)
{
return Task.CompletedTask;
}
}
}

View File

@ -0,0 +1,26 @@
using System;
using KonSoft.Admin.EntityFrameworkCore;
using KonSoft.Shared.Hosting.Microservices.DbMigrations.EfCore;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace KonSoft.Admin.DbMigrations
{
public class AdminPendingEfCoreMigrationsChecker : PendingEfCoreMigrationsChecker<AdminDbContext>
{
public AdminPendingEfCoreMigrationsChecker(IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IDistributedEventBus distributedEventBus,
IAbpDistributedLock abpDistributedLock) : base(unitOfWorkManager,
serviceProvider,
currentTenant,
distributedEventBus,
abpDistributedLock,
"Clean")
{
}
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>

View File

@ -0,0 +1,109 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace KonSoft.Shared.Hosting.Microservices.DbMigrations.EfCore
{
public abstract class PendingEfCoreMigrationsChecker<TDbContext> : ITransientDependency
where TDbContext : DbContext
{
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IServiceProvider ServiceProvider { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IDistributedEventBus DistributedEventBus { get; }
protected IAbpDistributedLock DistributedLockProvider { get; }
protected string DatabaseName { get; }
protected PendingEfCoreMigrationsChecker(
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IDistributedEventBus distributedEventBus,
IAbpDistributedLock abpDistributedLock,
string databaseName)
{
UnitOfWorkManager = unitOfWorkManager;
ServiceProvider = serviceProvider;
CurrentTenant = currentTenant;
DistributedEventBus = distributedEventBus;
DistributedLockProvider = abpDistributedLock;
DatabaseName = databaseName;
}
public virtual async Task CheckAndApplyDatabaseMigrationsAsync()
{
await TryAsync(LockAndApplyDatabaseMigrationsAsync);
}
protected async Task TryAsync(Func<Task> task, int retryCount = 3)
{
try
{
await task();
}
catch (Exception ex)
{
retryCount--;
if (retryCount <= 0)
{
throw;
}
Log.Warning($"{ex.GetType().Name} has been thrown. The operation will be tried {retryCount} times more. Exception:\n{ex.Message}");
await Task.Delay(RandomHelper.GetRandom(5000, 15000));
await TryAsync(task, retryCount);
}
}
protected virtual async Task LockAndApplyDatabaseMigrationsAsync()
{
await using (var handle = await DistributedLockProvider.TryAcquireAsync("Migration_" + DatabaseName))
{
Log.Information($"Lock is acquired for db migration and seeding on database named: {DatabaseName}...");
if (handle is null)
{
Log.Information($"Handle is null because of the locking for : {DatabaseName}");
return;
}
using (CurrentTenant.Change(null))
{
// Create database tables if needed
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
var dbContext = ServiceProvider.GetRequiredService<TDbContext>();
var pendingMigrations = await dbContext
.Database
.GetPendingMigrationsAsync();
if (pendingMigrations.Any())
{
await dbContext.Database.MigrateAsync();
}
await uow.CompleteAsync();
}
await ServiceProvider.GetRequiredService<IDataSeeder>()
.SeedAsync();
}
Log.Information($"Lock is released for db migration and seeding on database named: {DatabaseName}...");
}
}
}
}