using System.Collections.Concurrent; using System.Threading.Channels; using Domain.Interfaces; namespace Domain; public class RenderManager : IRenderManager { private readonly Channel _taskChannel; private readonly ConcurrentDictionary _renders = []; public RenderManager(int channelCapacity = 5) { var options = new BoundedChannelOptions(channelCapacity) { FullMode = BoundedChannelFullMode.Wait // Ожидание при переполнении канала }; _taskChannel = Channel.CreateBounded(options); } public Task StartRender(Project project) { var render = new Render(project); if (_renders.TryAdd(render.Id, render)) { _ =render.Run(_taskChannel); } _ = ProcessQueue(); return Task.FromResult(render.Id); } private async Task ProcessQueue(CancellationToken cancellationToken = default) { while (await _taskChannel.Reader.WaitToReadAsync(cancellationToken)) { while (_taskChannel.Reader.TryRead(out var task)) { try { await task.Execute(cancellationToken); } catch (OperationCanceledException) { // Console.WriteLine($"Task {task.RenderId} was cancelled."); } } } } public async Task StopRender(Guid renderId) { if (_renders.TryRemove(renderId, out var render)) { await render.Stop(); UpdateProjectHistoryToHistory(render.ProjectId, render.Id); } } private async Task ClearTasksForRender(Guid renderId) { var remainingTasks = new List(); while (await _taskChannel.Reader.WaitToReadAsync()) { if (_taskChannel.Reader.TryRead(out var task)) { // if (task.RenderId != renderId) // { // remainingTasks.Add(task); // } } } foreach (var task in remainingTasks) { await _taskChannel.Writer.WriteAsync(task); } } private void UpdateProjectHistoryToHistory(Guid projectId, Guid renderId) { Console.WriteLine($"UpdateProjectHistoryToHistory: {projectId}, {renderId}"); } public IEnumerable GetActiveRenders() { return new List(); } }