MES-ETL/MesETL.App/HostedServices/TransformService.cs

117 lines
4.3 KiB
C#
Raw Normal View History

using MesETL.App.Cache;
using MesETL.App.Const;
using MesETL.App.HostedServices.Abstractions;
using MesETL.App.Options;
using MesETL.App.Services;
using MesETL.App.Services.ErrorRecorder;
2023-12-29 16:16:05 +08:00
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace MesETL.App.HostedServices;
2023-12-29 16:16:05 +08:00
2024-01-29 09:29:16 +08:00
public record DataTransformContext(DataRecord Record, ICacher Cacher, ILogger Logger);
2024-01-04 09:00:44 +08:00
/// <summary>
/// 数据处理服务,对导入后的数据进行处理
/// </summary>
public class TransformService : ITransformService
2023-12-29 16:16:05 +08:00
{
private readonly ILogger _logger;
private readonly IOptions<DataTransformOptions> _options;
2024-01-29 09:29:16 +08:00
private readonly DataRecordQueue _producerQueue;
private readonly RecordQueuePool _queuePool;
2023-12-29 16:16:05 +08:00
private readonly ProcessContext _context;
2024-01-29 09:29:16 +08:00
private readonly ICacher _cache;
private readonly ErrorRecorderFactory _errorRecorderFactory;
2023-12-29 16:16:05 +08:00
2024-01-04 09:00:44 +08:00
public TransformService(ILogger<TransformService> logger,
IOptions<DataTransformOptions> options,
2024-01-29 09:29:16 +08:00
[FromKeyedServices(ProcessStep.Produce)] DataRecordQueue producerQueue,
RecordQueuePool queuePool,
ProcessContext context,
2024-01-29 09:29:16 +08:00
ICacher cache,
ErrorRecorderFactory errorRecorderFactory)
2023-12-29 16:16:05 +08:00
{
_logger = logger;
_options = options;
2024-01-29 09:29:16 +08:00
_producerQueue = producerQueue;
_queuePool = queuePool;
2023-12-29 16:16:05 +08:00
_context = context;
_cache = cache;
2024-01-29 09:29:16 +08:00
_errorRecorderFactory = errorRecorderFactory;
2023-12-29 16:16:05 +08:00
}
2024-01-29 09:29:16 +08:00
public async Task ExecuteAsync(CancellationToken cancellationToken)
2023-12-29 16:16:05 +08:00
{
_logger.LogInformation("***** Data transform service started, thread id: {ThreadId} *****", Environment.CurrentManagedThreadId);
2024-01-18 14:36:36 +08:00
2024-01-29 09:29:16 +08:00
while (!_context.IsInputCompleted || _producerQueue.Count > 0)
2023-12-29 16:16:05 +08:00
{
2024-01-29 09:29:16 +08:00
if (!_producerQueue.TryDequeue(out var record)) continue;
2023-12-29 16:16:05 +08:00
2024-01-29 09:29:16 +08:00
try
{
var context = new DataTransformContext(record, _cache, _logger);
if (_options.Value.EnableFilter)
2024-01-18 14:36:36 +08:00
{
2024-01-29 09:29:16 +08:00
// 数据过滤
var filter = _options.Value.RecordFilter;
if (filter is not null && await filter(context) == false) continue;
2024-01-18 14:36:36 +08:00
}
2024-01-29 09:29:16 +08:00
if (_options.Value.EnableReplacer)
{
// 数据替换
var replacer = _options.Value.RecordModify;
if (replacer is not null)
{
record = await replacer(context);
}
}
// 字段缓存
var cacher = _options.Value.RecordCache;
if(cacher is not null)
await cacher.Invoke(context);
//计算需要分流的数据库
2024-01-29 09:29:16 +08:00
var dbFilter = _options.Value.DatabaseFilter
?? throw new ApplicationException("未配置数据库过滤器");
record.Database = dbFilter(record);
_queuePool[record.Database].Enqueue(record);
2024-01-18 14:36:36 +08:00
_context.AddTransform();
2024-01-29 09:29:16 +08:00
if (_options.Value.EnableReBuilder)
2024-01-18 14:36:36 +08:00
{
2024-01-29 09:29:16 +08:00
//数据重建
var addRecords = _options.Value.RecordReBuild?.Invoke(context);
if (addRecords is { Count: > 0 })
2024-01-18 14:36:36 +08:00
{
2024-01-29 09:29:16 +08:00
foreach (var rc in addRecords)
{
if(dbFilter is not null)
rc.Database =dbFilter.Invoke(record);
_queuePool[record.Database].Enqueue(rc);
_context.AddTransform();
}
2024-01-18 14:36:36 +08:00
}
}
}
2024-01-29 09:29:16 +08:00
catch (Exception e)
{
_context.AddException(e);
var errorRecorder = _errorRecorderFactory.CreateTransform();
await errorRecorder.LogErrorRecordAsync(record, e);
if (!_options.Value.StrictMode)
_logger.LogError(e, "数据转换时发生错误");
else throw;
}
}
_context.CompleteTransform();
_logger.LogInformation("***** Data transformation service finished *****");
2023-12-29 16:16:05 +08:00
}
}