feat: Add monitoring alerts skeleton and enhance worker with notifications
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Domain.Enums;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CMSMicroservice.Infrastructure.Services;
|
||||
|
||||
/// <summary>
|
||||
/// پیادهسازی سرویس محاسبه موقعیت در Binary Tree
|
||||
/// </summary>
|
||||
public class NetworkPlacementService : INetworkPlacementService
|
||||
{
|
||||
private readonly IApplicationDbContext _context;
|
||||
private readonly ILogger<NetworkPlacementService> _logger;
|
||||
|
||||
public NetworkPlacementService(
|
||||
IApplicationDbContext context,
|
||||
ILogger<NetworkPlacementService> logger)
|
||||
{
|
||||
_context = context;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<NetworkLeg?> CalculateLegPositionAsync(long parentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// بررسی وجود Parent
|
||||
var parentExists = await _context.Users.AnyAsync(u => u.Id == parentId, cancellationToken);
|
||||
if (!parentExists)
|
||||
{
|
||||
_logger.LogWarning("Parent {ParentId} does not exist", parentId);
|
||||
return null;
|
||||
}
|
||||
|
||||
// شمارش فرزندان فعلی
|
||||
var children = await _context.Users
|
||||
.Where(u => u.NetworkParentId == parentId)
|
||||
.Select(u => new { u.LegPosition })
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
if (children.Count >= 2)
|
||||
{
|
||||
_logger.LogWarning("Parent {ParentId} already has 2 children. Binary Tree is full!", parentId);
|
||||
return null; // Binary Tree پر است
|
||||
}
|
||||
|
||||
// بررسی کدام Leg خالی است
|
||||
var hasLeft = children.Any(c => c.LegPosition == NetworkLeg.Left);
|
||||
var hasRight = children.Any(c => c.LegPosition == NetworkLeg.Right);
|
||||
|
||||
if (!hasLeft)
|
||||
{
|
||||
_logger.LogDebug("Parent {ParentId}: Left leg is available", parentId);
|
||||
return NetworkLeg.Left;
|
||||
}
|
||||
|
||||
if (!hasRight)
|
||||
{
|
||||
_logger.LogDebug("Parent {ParentId}: Right leg is available", parentId);
|
||||
return NetworkLeg.Right;
|
||||
}
|
||||
|
||||
// نباید به اینجا برسیم (چون Count < 2 بود)
|
||||
_logger.LogError("Unexpected state: Parent {ParentId} has {Count} children but no available leg",
|
||||
parentId, children.Count);
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<bool> CanAcceptChildAsync(long parentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var childCount = await _context.Users
|
||||
.CountAsync(u => u.NetworkParentId == parentId, cancellationToken);
|
||||
|
||||
return childCount < 2;
|
||||
}
|
||||
|
||||
public async Task<long?> FindAvailableParentAsync(long rootParentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// BFS (Breadth-First Search) برای پیدا کردن اولین Parent با جای خالی
|
||||
var queue = new Queue<long>();
|
||||
queue.Enqueue(rootParentId);
|
||||
var visited = new HashSet<long>();
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var currentParentId = queue.Dequeue();
|
||||
|
||||
if (visited.Contains(currentParentId))
|
||||
continue;
|
||||
|
||||
visited.Add(currentParentId);
|
||||
|
||||
// بررسی کنید که آیا این Parent میتواند فرزند بپذیرد
|
||||
var canAccept = await CanAcceptChildAsync(currentParentId, cancellationToken);
|
||||
if (canAccept)
|
||||
{
|
||||
_logger.LogInformation("Found available parent: {ParentId}", currentParentId);
|
||||
return currentParentId;
|
||||
}
|
||||
|
||||
// اضافه کردن فرزندان به صف برای جستجو
|
||||
var children = await _context.Users
|
||||
.Where(u => u.NetworkParentId == currentParentId)
|
||||
.Select(u => u.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
foreach (var childId in children)
|
||||
{
|
||||
queue.Enqueue(childId);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogWarning("No available parent found in network starting from {RootParentId}", rootParentId);
|
||||
return null; // هیچ Parent خالی پیدا نشد
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user