ISEbd-22_Baygulov_A.A._Sush.../SushiBar/SushiBarBusinessLogic/WorkModeling.cs
2024-05-22 21:31:27 +04:00

147 lines
3.6 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.Extensions.Logging;
using SushiBarContracts.BindingModels;
using SushiBarContracts.BusinessLogicsContracts;
using SushiBarContracts.SearchModels;
using SushiBarContracts.ViewModels;
using SushiBarDataModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SushiBarBusinessLogic
{
public class WorkModeling : IWorkProcess
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> Logger)
{
_logger = Logger;
_rnd = new Random(1000);
}
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{
_orderLogic = orderLogic;
var implementers = implementerLogic.ReadList(null);
if (implementers == null)
{
_logger.LogWarning("DoWork. Implementers is null");
return;
}
var orders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Принят });
if (orders == null || orders.Count == 0)
{
_logger.LogWarning("DoWork. Orders is null or empty");
return;
}
_logger.LogDebug("DoWork for {Count} orders", orders.Count);
foreach (var implementer in implementers)
{
Task.Run(() => WorkerWorkAsync(implementer, orders));
}
}
private async Task WorkerWorkAsync(ImplementerViewModel Implementer, List<OrderViewModel> Orders)
{
if (_orderLogic == null || Implementer == null)
{
return;
}
await RunOrderInWork(Implementer);
await Task.Run(() =>
{
foreach (var Order in Orders)
{
try
{
_logger.LogDebug("WorkerWorkAsync. Worker {Id} try get order {Order}", Implementer.Id, Order.Id);
bool AcquireResult = _orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = Order.Id,
ImplementerId = Implementer.Id
});
if (!AcquireResult)
{
_logger.LogDebug("WorkerWorkAsync. Worker {Id} tried to get order {Order} but it's already acquired by other worker", Implementer.Id, Order.Id);
continue;
}
Thread.Sleep(Implementer.WorkExperience * _rnd.Next(100, 1000) * Order.Count);
_logger.LogDebug("WorkerWorkAsync. Worker {Id} finish order {Order}", Implementer.Id, Order.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = Order.Id
});
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
Thread.Sleep(Implementer.Qualification * _rnd.Next(10, 100));
}
});
}
private async Task RunOrderInWork(ImplementerViewModel Implementer)
{
if (_orderLogic == null || Implementer == null)
return;
try
{
var RunOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = Implementer.Id,
Status = OrderStatus.Выполняется
}));
if (RunOrder == null)
{
return;
}
_logger.LogDebug("RunOrderInWork. Worker {Id} back to order {Order}", Implementer.Id, RunOrder.Id);
Thread.Sleep(Implementer.WorkExperience * _rnd.Next(100, 300) * RunOrder.Count);
_logger.LogDebug("RunOrderInWork. Worker {Id} finish order {Order}", Implementer.Id, RunOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = RunOrder.Id
});
Thread.Sleep(Implementer.Qualification * _rnd.Next(10, 100));
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
}
}