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;
|
2024-01-16 15:35:54 +08:00
|
|
|
|
private readonly IOptions<DatabaseOutputOptions> _outputOptions;
|
|
|
|
|
private readonly IOptions<DataTransformOptions> _transformOptions;
|
2023-12-29 16:16:05 +08:00
|
|
|
|
private readonly ProcessContext _context;
|
2024-01-04 09:00:44 +08:00
|
|
|
|
private readonly TaskManager _taskManager;
|
2024-01-18 15:03:45 +08:00
|
|
|
|
private readonly ErrorRecorder _errorRecorder;
|
2023-12-29 16:16:05 +08:00
|
|
|
|
|
2024-01-04 09:00:44 +08:00
|
|
|
|
public OutputService(ILogger<OutputService> logger,
|
2024-01-16 15:35:54 +08:00
|
|
|
|
IOptions<DatabaseOutputOptions> outputOptions,
|
2024-01-04 09:00:44 +08:00
|
|
|
|
ProcessContext context,
|
2024-01-16 15:35:54 +08:00
|
|
|
|
TaskManager taskManager,
|
2024-01-18 15:03:45 +08:00
|
|
|
|
IOptions<DataTransformOptions> transformOptions,
|
|
|
|
|
ErrorRecorder errorRecorder)
|
2023-12-29 16:16:05 +08:00
|
|
|
|
{
|
|
|
|
|
_logger = logger;
|
2024-01-16 15:35:54 +08:00
|
|
|
|
_outputOptions = outputOptions;
|
2023-12-29 16:16:05 +08:00
|
|
|
|
_context = context;
|
2024-01-04 09:00:44 +08:00
|
|
|
|
_taskManager = taskManager;
|
2024-01-16 15:35:54 +08:00
|
|
|
|
_transformOptions = transformOptions;
|
2024-01-18 15:03:45 +08:00
|
|
|
|
_errorRecorder = errorRecorder;
|
2023-12-29 16:16:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-19 13:47:35 +08:00
|
|
|
|
public async Task ExecuteAsync(TasksOptions tasksOptions, DataRecordQueue consumerQueue, ProcessContext context, CancellationToken cancellationToken)
|
2023-12-29 16:16:05 +08:00
|
|
|
|
{
|
2024-01-19 13:47:35 +08:00
|
|
|
|
|
2023-12-29 16:16:05 +08:00
|
|
|
|
_logger.LogInformation("***** Mysql output service started *****");
|
2024-01-19 13:47:35 +08:00
|
|
|
|
|
|
|
|
|
var records = new List<DataRecord>();
|
|
|
|
|
while (!context.IsTransformCompleted || consumerQueue.Count > 0)
|
2023-12-29 16:16:05 +08:00
|
|
|
|
{
|
2024-01-19 13:47:35 +08:00
|
|
|
|
if (!consumerQueue.TryDequeue(out var record)) continue;
|
|
|
|
|
records.Add(record);
|
|
|
|
|
if (records.Count >= tasksOptions.OutPutOptions.FlushCount)
|
2023-12-29 16:16:05 +08:00
|
|
|
|
{
|
2024-01-19 15:14:01 +08:00
|
|
|
|
var temp= new List<DataRecord>(records);
|
2024-01-19 13:47:35 +08:00
|
|
|
|
ThreadPool.QueueUserWorkItem(async (queueState) =>
|
2024-01-19 15:14:01 +08:00
|
|
|
|
{
|
|
|
|
|
await FlushAsync(temp);
|
|
|
|
|
});
|
2024-01-19 13:47:35 +08:00
|
|
|
|
|
|
|
|
|
records.Clear();
|
2023-12-29 16:16:05 +08:00
|
|
|
|
}
|
2024-01-19 13:47:35 +08:00
|
|
|
|
if (_context.GetExceptions().Count > 0)
|
2023-12-29 16:16:05 +08:00
|
|
|
|
{
|
2024-01-19 13:47:35 +08:00
|
|
|
|
_logger.LogInformation("***** Csv output thread is canceled *****");
|
|
|
|
|
return;
|
2023-12-29 16:16:05 +08:00
|
|
|
|
}
|
2024-01-19 13:47:35 +08:00
|
|
|
|
}
|
|
|
|
|
if (records.Count > 0)
|
|
|
|
|
{
|
2024-01-19 15:14:01 +08:00
|
|
|
|
var temp = new List<DataRecord>(records);
|
2024-01-19 13:47:35 +08:00
|
|
|
|
ThreadPool.QueueUserWorkItem(async (queueState) =>
|
|
|
|
|
{
|
|
|
|
|
await FlushAsync(temp);
|
|
|
|
|
});
|
|
|
|
|
records.Clear();
|
|
|
|
|
_logger.LogInformation("***** Mysql output thread completed *****");
|
|
|
|
|
}
|
2023-12-29 16:16:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task FlushAsync(IEnumerable<DataRecord> records)
|
|
|
|
|
{
|
|
|
|
|
var count = 0;
|
2024-01-04 09:00:44 +08:00
|
|
|
|
await using var output = new MySqlDestination(
|
2024-01-16 15:35:54 +08:00
|
|
|
|
_outputOptions.Value.ConnectionString ?? throw new InvalidOperationException("Connection string is required"),
|
2024-01-18 15:03:45 +08:00
|
|
|
|
_logger, _context, _transformOptions, _errorRecorder);
|
2024-01-12 16:50:37 +08:00
|
|
|
|
//if (records == null || records.Count() == 0) return;
|
|
|
|
|
//var dbName = $"cferp_test_1";
|
|
|
|
|
//if (records != null && records.Count() > 0)
|
|
|
|
|
//{
|
|
|
|
|
// dbName = $"cferp_test_{records.FirstOrDefault()?.CompanyID}";
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//await using var output = new MySqlDestination(new MySqlConnectionStringBuilder
|
|
|
|
|
//{
|
|
|
|
|
// Server = "127.0.0.1",
|
|
|
|
|
// Port = 34309,
|
|
|
|
|
// Database = dbName,
|
|
|
|
|
// UserID = "root",
|
|
|
|
|
// Password = "123456",
|
|
|
|
|
// MaximumPoolSize = 50,
|
|
|
|
|
//}.ConnectionString, _logger,true);
|
2023-12-29 16:16:05 +08:00
|
|
|
|
foreach (var record in records)
|
|
|
|
|
{
|
|
|
|
|
await output.WriteRecordAsync(record);
|
|
|
|
|
count++;
|
|
|
|
|
}
|
2024-01-16 15:35:54 +08:00
|
|
|
|
await output.FlushAsync(_outputOptions.Value.MaxAllowedPacket);
|
2023-12-29 16:16:05 +08:00
|
|
|
|
_context.AddOutput(count);
|
|
|
|
|
}
|
|
|
|
|
}
|