Blame view

泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/MultiTenancy/ThTenantDatabaseBackgroundInitializer.cs 2.22 KB
1e73afce   李曜臣   代码优化
1
2
3
4
  using System.Collections.Concurrent;
  using Microsoft.Extensions.DependencyInjection;
  using Microsoft.Extensions.Logging;
  using Volo.Abp.DependencyInjection;
e41dfa09   李曜臣   泰鄂版菜单;租户列表
5
  using Volo.Abp.Uow;
1e73afce   李曜臣   代码优化
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  using Yi.Framework.TenantManagement.Application.Contracts;
  
  namespace FoodLabeling.Th.Application.MultiTenancy;
  
  /// <summary>
  /// 使用独立 DI Scope 在后台执行 <see cref="ITenantService.InitAsync"/>,避免阻塞 HTTP 请求。
  /// </summary>
  public class ThTenantDatabaseBackgroundInitializer
      : IThTenantDatabaseBackgroundInitializer, ISingletonDependency
  {
      private readonly IServiceScopeFactory _scopeFactory;
      private readonly ILogger<ThTenantDatabaseBackgroundInitializer> _logger;
      private static readonly ConcurrentDictionary<Guid, byte> Running = new();
  
      public ThTenantDatabaseBackgroundInitializer(
          IServiceScopeFactory scopeFactory,
          ILogger<ThTenantDatabaseBackgroundInitializer> logger)
      {
          _scopeFactory = scopeFactory;
          _logger = logger;
      }
  
      /// <inheritdoc />
      public void Enqueue(Guid tenantId)
      {
          if (!Running.TryAdd(tenantId, 0))
          {
              _logger.LogInformation("租户 {TenantId} 业务库初始化已在进行中,跳过重复入队", tenantId);
              return;
          }
  
          _ = Task.Run(() => RunInitAsync(tenantId));
      }
  
      private async Task RunInitAsync(Guid tenantId)
      {
          try
          {
              _logger.LogInformation("租户 {TenantId} 业务库后台初始化开始", tenantId);
  
              using var scope = _scopeFactory.CreateScope();
e41dfa09   李曜臣   泰鄂版菜单;租户列表
47
              var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
1e73afce   李曜臣   代码优化
48
              var tenantService = scope.ServiceProvider.GetRequiredService<ITenantService>();
e41dfa09   李曜臣   泰鄂版菜单;租户列表
49
50
  
              using var uow = uowManager.Begin(requiresNew: true, isTransactional: false);
1e73afce   李曜臣   代码优化
51
              await tenantService.InitAsync(tenantId);
e41dfa09   李曜臣   泰鄂版菜单;租户列表
52
              await uow.CompleteAsync();
1e73afce   李曜臣   代码优化
53
54
55
56
57
58
59
60
61
62
63
64
65
  
              _logger.LogInformation("租户 {TenantId} 业务库后台初始化完成", tenantId);
          }
          catch (Exception ex)
          {
              _logger.LogError(ex, "租户 {TenantId} 业务库后台初始化失败", tenantId);
          }
          finally
          {
              Running.TryRemove(tenantId, out _);
          }
      }
  }