Merge branch 'master' of https://git.konsoft.top/konsoft/KonSoft.Clean
This commit is contained in:
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
|||||||
@ -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}...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user