MES-ETL/Mesdb.DataGenerator/MockInputService.cs

60 lines
2.3 KiB
C#

using System.Runtime;
using MesETL.App.Const;
using MesETL.App.HostedServices.Abstractions;
using MesETL.App.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Mesdb.DataGenerator;
public class MockInputService : IInputService
{
private readonly DataRecordQueue _producerQueue;
private readonly ProcessContext _context;
private readonly IOptions<MockInputOptions> _options;
private readonly ILogger _logger;
private readonly long _memoryThreshold;
public MockInputService([FromKeyedServices(ConstVar.Producer)]DataRecordQueue producerQueue, ProcessContext context, IOptions<MockInputOptions> options,
ILogger<MockInputService> logger, IConfiguration configuration)
{
_producerQueue = producerQueue;
_context = context;
_options = options;
_logger = logger;
_memoryThreshold = (long)(configuration.GetValue<double>("MemoryThreshold", 8) * 1024 * 1024 * 1024);
}
public async Task ExecuteAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("***** 开始模拟输入数据 *****");
foreach (var (table, options) in _options.Value.Rules)
{
_logger.LogInformation("模拟表 '{TableName}' 输入,数量: {Amount}", table, options.Amount);
for (int i = 0; i < options.Amount; i++)
{
if (GC.GetTotalMemory(false) > _memoryThreshold)
{
_logger.LogWarning("内存使用率过高,暂缓输入");
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
await Task.Delay(3000, cancellationToken);
}
var ctx = new TableMockContext()
{
Index = i,
};
var record = options.Generate(ctx);
await _producerQueue.EnqueueAsync(record);
_context.AddInput(1);
_context.AddTableInput(table, 1);
}
_logger.LogInformation("表 '{TableName}' 输入完成", table);
}
_context.CompleteInput();
_logger.LogInformation("***** 模拟数据输入完成 *****");
}
}