ПИбд-21, Лёвушкина Анна, лаб6 сложная #21

Closed
AnnaLioness wants to merge 6 commits from лаб6_сложная into лаб5_сложная
3 changed files with 215 additions and 127 deletions
Showing only changes of commit 98967a8537 - Show all commits

View File

@ -85,12 +85,18 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
_logger.LogWarning("Read operation failed"); _logger.LogWarning("Read operation failed");
return false; return false;
} }
if (element.Status != status - 1) if (element.Status != status - 1 && element.Status != OrderStatus.Ожидание)
{ {
_logger.LogWarning("Status change operation failed"); _logger.LogWarning("Status change operation failed");
throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный"); throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный");
} }
if (status == OrderStatus.Готов) if (element.ImplementerId.HasValue)
model.ImplementerId = element.ImplementerId;
if (model.DocumentId == 0)
model.DocumentId = element.DocumentId;
if (model.Count == 0)
model.Count = element.Count;
if (status == OrderStatus.Выдан)
{ {
var document = _documentStorage.GetElement(new DocumentSearchModel() { Id = model.DocumentId }); var document = _documentStorage.GetElement(new DocumentSearchModel() { Id = model.DocumentId });
if (document == null) if (document == null)
@ -102,7 +108,10 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
if (!CheckThenSupplyMany(document, model.Count)) if (!CheckThenSupplyMany(document, model.Count))
{ {
_logger.LogWarning("Status change operation failed. Shop supply error."); _logger.LogWarning("Status change operation failed. Shop supply error.");
return false; model.Status = OrderStatus.Ожидание;
if (_orderStorage.Update(model) == null)
_logger.LogWarning("Update operation failed");
return false;
} }
} }

View File

@ -14,128 +14,206 @@ namespace AbstractLawFirmBusinessLogic.BusinessLogic
{ {
public class WorkModeling : IWorkProcess public class WorkModeling : IWorkProcess
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly Random _rnd; private readonly Random _rnd;
private IOrderLogic? _orderLogic; 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("DoWork. Worker {Id} try get order { Order}", implementer.Id, order.Id);
// пытаемся назначить заказ на исполнителя
_orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = order.Id,
ImplementerId = implementer.Id
});
// делаем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order { Order}", implementer.Id, order.Id);
_orderLogic.FinishOrder(new OrderBindingModel public WorkModeling(ILogger<WorkModeling> logger)
{ {
Id = order.Id _logger = logger;
}); _rnd = new Random(1000);
} }
// кто-то мог уже перехватить заказ, игнорируем ошибку
catch (InvalidOperationException ex) public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{ {
_logger.LogWarning(ex, "Error try get work"); _orderLogic = orderLogic;
} var implementers = implementerLogic.ReadList(null);
// заканчиваем выполнение имитации в случае иной ошибки if (implementers == null)
catch (Exception ex) {
{ _logger.LogWarning("DoWork. Implementers is null");
_logger.LogError(ex, "Error while do work"); return;
throw; }
}
// отдыхаем var orders = _orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Принят });
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100)); if (orders == null)
} {
}); _logger.LogWarning("DoWork. Orders is null");
} return;
/// Ищем заказ, которые уже в работе (вдруг исполнителя прервали) }
private async Task RunOrderInWork(ImplementerViewModel implementer) orders.AddRange(_orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Выполняется }) ?? new());
{ orders.AddRange(_orderLogic.ReadList(new OrderSearchModel { Status = OrderStatus.Ожидание }) ?? new());
if (_orderLogic == null || implementer == null) if (orders.Count == 0)
{ {
return; _logger.LogWarning("DoWork. Orders is empty");
} return;
try }
{
var runOrder = await Task.Run(() => _orderLogic.ReadElement(new _logger.LogDebug("DoWork for {Count} orders", orders.Count);
OrderSearchModel
{ foreach (var implementer in implementers)
ImplementerId = implementer.Id, {
Status = OrderStatus.Выполняется Task.Run(() => WorkerWorkAsync(implementer, orders));
})); }
if (runOrder == null) }
{
return; /// <summary>
} /// Иммитация работы исполнителя
_logger.LogDebug("DoWork. Worker {Id} back to order {Order}", /// </summary>
implementer.Id, runOrder.Id); /// <param name="implementer"></param>
// доделываем работу /// <param name="orders"></param>
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count); private async Task WorkerWorkAsync(ImplementerViewModel implementer, List<OrderViewModel> orders)
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", {
implementer.Id, runOrder.Id); if (_orderLogic == null || implementer == null)
_orderLogic.FinishOrder(new OrderBindingModel {
{ return;
Id = runOrder.Id }
});
// отдыхаем await RunWaitingOrder(implementer);
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
} await RunOrderInWork(implementer);
// заказа может не быть, просто игнорируем ошибку
catch (InvalidOperationException ex) await Task.Run(() =>
{ {
_logger.LogWarning(ex, "Error try get work"); foreach (var order in orders)
} {
// а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации try
catch (Exception ex) {
{ _logger.LogDebug("DoWork. Worker {Id} try get order {Order}", implementer.Id, order.Id);
_logger.LogError(ex, "Error while do work"); // пытаемся назначить заказ на исполнителя
throw; _orderLogic.TakeOrderInWork(new OrderBindingModel
} {
} Id = order.Id,
} ImplementerId = implementer.Id
});
// делаем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = order.Id
});
// доставляем
_logger.LogDebug("DoWork. Worker {Id} delivery order {Order}", implementer.Id, order.Id);
_orderLogic.DeliveryOrder(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));
}
});
}
/// <summary>
/// Ищем заказ, которые уже в работе (вдруг исполнителя прервали)
/// </summary>
/// <param name="implementer"></param>
/// <returns></returns>
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("DoWork. Worker {Id} back to order {Order}", implementer.Id, runOrder.Id);
// доделываем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, runOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = runOrder.Id
});
// доставляем
_logger.LogDebug("DoWork. Worker {Id} delivery order {Order}", implementer.Id, runOrder.Id);
_orderLogic.DeliveryOrder(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;
}
}
/// <summary>
/// Ищем заказ, которые ждут выдачи (вдруг место освободилось)
/// </summary>
/// <param name="implementer"></param>
/// <returns></returns>
private async Task RunWaitingOrder(ImplementerViewModel implementer)
{
if (_orderLogic == null || implementer == null)
{
return;
}
try
{
var order = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = implementer.Id,
Status = OrderStatus.Ожидание
}));
if (order == null)
{
return;
}
// доставляем
_logger.LogDebug("DoWork. Worker {Id} delivery order {Order}", implementer.Id, order.Id);
_orderLogic.DeliveryOrder(new OrderBindingModel
{
Id = order.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;
}
}
}
} }

View File

@ -12,6 +12,7 @@ namespace AbstractLawFirmDataModels.Enums
Принят = 0, Принят = 0,
Выполняется = 1, Выполняется = 1,
Готов = 2, Готов = 2,
Выдан = 3 Выдан = 3,
Ожидание = 4
} }
} }