using Quadarax.Foundation.Core.Business.Processor.Enums; using Quadarax.Foundation.Core.Business.Processor.Task; using Quadarax.Foundation.Core.Logging; namespace Quadarax.Foundation.Core.Business.Processor.Queue { internal class TaskSlots { #region *** Properties *** public int FreeSlotsCount => _taskSlots.Count(x => x == null); #endregion #region *** Fields *** private ITaskItem?[] _taskSlots; private readonly ILog _log; #endregion #region *** Indexer *** public ITaskItem? this[int ordinal] => GetSlot(ordinal); #endregion #region *** Constructor *** public TaskSlots(int initialMaxSlots) { _taskSlots = new ITaskItem?[initialMaxSlots]; _log = new ConsoleLogger().GetLogger(nameof(TaskSlots)); } #endregion #region *** Public Operations *** public int AssignSlot(ITaskItem task) { if(task == null) throw new ArgumentNullException(nameof(task)); var ordinal = GetNextFreeSlotOrdinal(); if (ordinal == -1) return -1; _taskSlots[ordinal] = task; _log.Log(LogSeverityEnum.Debug, $"Task ({task}) assigned to slot # {ordinal}"); return ordinal; } public ITaskItem? GetSlot(int ordinal) { if (ordinal < 0 || ordinal >= _taskSlots.Length) throw new ArgumentOutOfRangeException(nameof(ordinal)); return _taskSlots[ordinal]; } public void ReleaseSlot(int ordinal) { var task = GetSlot(ordinal); if (task == null) return; if (task.Status == ProcessStatusEnum.Started) task.Stop("(System) Paused due change configuration.", true, false); _taskSlots[ordinal] = null; _log.Log(LogSeverityEnum.Debug, $"Task ({task}) was released from slot # {ordinal}"); } public void ReleaseAll() { _log.Log(LogSeverityEnum.Debug, "Releasing all slots ..."); for (var a = 0; a < _taskSlots.Length; a++) ReleaseSlot(a); } public void SetMaxSlots(int maxSlots) { _log.Log(LogSeverityEnum.Debug, $"Set max slots from {_taskSlots.Length} to {maxSlots}"); if (maxSlots < 1) throw new ArgumentOutOfRangeException(nameof(maxSlots)); ReleaseAll(); _taskSlots = new ITaskItem[maxSlots]; } #endregion #region *** Private Operations *** private int GetNextFreeSlotOrdinal() { for (var i = 0; i < _taskSlots.Length; i++) { if (_taskSlots[i] == null) return i; } return -1; } #endregion } }