MES-ETL/ConsoleApp2/HostedServices/OutputService.cs

83 lines
2.6 KiB
C#
Raw Normal View History

2024-01-04 09:00:44 +08:00
using ConsoleApp2.Const;
using ConsoleApp2.HostedServices.Abstractions;
2023-12-29 16:16:05 +08:00
using ConsoleApp2.Options;
using ConsoleApp2.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace ConsoleApp2.HostedServices;
2024-01-04 09:00:44 +08:00
/// <summary>
/// 数据导出服务将数据导出至MySql服务
/// </summary>
public class OutputService : IOutputService
2023-12-29 16:16:05 +08:00
{
private readonly ILogger _logger;
private readonly DataRecordQueue _consumerQueue;
2024-01-04 09:00:44 +08:00
private readonly IOptions<DatabaseOutputOptions> _options;
2023-12-29 16:16:05 +08:00
private readonly ProcessContext _context;
2024-01-04 09:00:44 +08:00
private readonly TaskManager _taskManager;
2023-12-29 16:16:05 +08:00
2024-01-04 09:00:44 +08:00
public OutputService(ILogger<OutputService> logger,
[FromKeyedServices(ProcessStep.Consumer)] DataRecordQueue consumerQueue,
IOptions<DatabaseOutputOptions> options,
ProcessContext context,
TaskManager taskManager)
2023-12-29 16:16:05 +08:00
{
_logger = logger;
_consumerQueue = consumerQueue;
_options = options;
_context = context;
2024-01-04 09:00:44 +08:00
_taskManager = taskManager;
2023-12-29 16:16:05 +08:00
}
2024-01-04 09:00:44 +08:00
public async Task ExecuteAsync(CancellationToken stoppingToken)
2023-12-29 16:16:05 +08:00
{
_logger.LogInformation("***** Mysql output service started *****");
var records = new List<DataRecord>();
while (!_context.IsTransformCompleted || _consumerQueue.Count > 0)
{
if (!_consumerQueue.TryDequeue(out var record)) continue;
records.Add(record);
2024-01-04 09:00:44 +08:00
if (records.Count >= _options.Value.FlushCount)
2023-12-29 16:16:05 +08:00
{
var recordsCopy = records;
2024-01-04 09:00:44 +08:00
_taskManager.CreateTask(async () => await FlushAsync(recordsCopy), stoppingToken);
2023-12-29 16:16:05 +08:00
records = [];
}
2024-01-04 09:00:44 +08:00
if (_taskManager.TaskCount >= _options.Value.MaxTask)
2023-12-29 16:16:05 +08:00
{
2024-01-04 09:00:44 +08:00
await _taskManager.WaitAll();
_taskManager.ClearTask();
2023-12-29 16:16:05 +08:00
}
}
2024-01-04 09:00:44 +08:00
await _taskManager.WaitAll();
2023-12-29 16:16:05 +08:00
await FlushAsync(records);
2024-01-04 09:00:44 +08:00
2023-12-29 16:16:05 +08:00
_context.CompleteOutput();
2024-01-04 09:00:44 +08:00
2023-12-29 16:16:05 +08:00
_logger.LogInformation("***** Mysql output service completed *****");
}
private async Task FlushAsync(IEnumerable<DataRecord> records)
{
var count = 0;
2024-01-04 09:00:44 +08:00
await using var output = new MySqlDestination(
_options.Value.ConnectionString ?? throw new InvalidOperationException("Connection string is required"),
_logger, true);
2023-12-29 16:16:05 +08:00
foreach (var record in records)
{
await output.WriteRecordAsync(record);
count++;
}
await output.FlushAsync();
_context.AddOutput(count);
}
}