using System.Collections.Concurrent; using qdr.fnd.core.pqueue.Enums; using qdr.fnd.core.pqueue.Exceptions; using Quadarax.Foundation.Core.Data; using Quadarax.Foundation.Core.Logging; namespace qdr.fnd.core.pqueue.Storages { public class MemoryStorageProvider : BaseStorageProvider { private ConcurrentDictionary _items = new ConcurrentDictionary(); /// public MemoryStorageProvider(ILogger? logger) : base(logger) { } #region Overrides of BaseStorageProvider #endregion #region Overrides of DisposableObject /// protected override void OnDisposing() { _items.Clear(); _items = null!; } #endregion #region Overrides of BaseStorageProvider /// protected override string OnCreateItem(string id, string owner, string ownerRef, string providerClass, int initialAttempts, DateTime created) { var item = new PsQueueItem(id, owner, ownerRef, providerClass, created, null) { AttemptsLeft = initialAttempts }; if(!_items.TryAdd(id, item)) Log?.Log(LogSeverityEnum.Warn, $"Item id={id} already exists in storage (id conflict)"); return id; } /// protected override void OnDeleteItem(string itemId) { if(!_items.TryRemove(itemId, out _)) Log?.Log(LogSeverityEnum.Warn, $"Item id={itemId} wasn't delete from storage (not exists)"); } /// protected override void OnUpdateItemPriority(string itemId, int priority) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); item.Priority = priority; } /// protected override void OnUpdateItemValidity(string itemId, DateTime validForm, DateTime? validTo) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); item.ValidFrom = validForm; item.ValidTo = validTo; } /// protected override void OnUpdateItemStatus(string itemId, PsStatusEnum? status, bool isTransient) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); if (status!= null) item.Status = status.Value; item.IsStatusTransient = isTransient; } /// protected override void OnUpdateItemAttempts(string itemId, int attemptsLeft) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); item.AttemptsLeft = attemptsLeft; } /// protected override void OnUpdateItemStarted(string itemId, DateTime? started) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); item.Started = started; } /// protected override void OnUpdateItemFinished(string itemId, DateTime? finished) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); item.Finished = finished; } /// protected override void OnCreateItemAttribute(string itemId, string name, string? value, string valueTypeClass, bool isOutput) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); var type = Type.GetType(valueTypeClass); ((List)item.Arguments).Add(new TypedArgument(name, value, type,isOutput)); } /// protected override void OnUpdateItemAttribute(string itemId, string name, string value) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); var attr = item.Arguments.FirstOrDefault(a => string.Equals(a.Name , name,StringComparison.CurrentCultureIgnoreCase)); if(attr== null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemArgumentNotFound, itemId, name); ((TypedArgument)attr).Value = value; } /// protected override void OnDeleteItemAttribute(string itemId, string name) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); var attr = item.Arguments.FirstOrDefault(a => string.Equals(a.Name , name,StringComparison.CurrentCultureIgnoreCase)); if(attr== null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemArgumentNotFound, itemId, name); ((List)item.Arguments).Remove(attr); } /// protected override void OnAppendLog(string itemId, string message, int code, ErrorLevelEnum messageType) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); ((List)item.Log).Add(new Error(message, code, messageType, DateTime.Now)); } /// protected override void OnAppendStatusJournal(string itemId, PsStatusEnum status, bool isTransient, string message) { var item = (PsQueueItem)GetItem(itemId); if (item == null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); ((List)item.StatusJournal).Add(new PsStatusHistory(status, isTransient,message)); } /// protected override IQueryable OnQuery() { return _items.Values.AsQueryable(); } /// protected override IPsQueueItem OnGetItem(string itemId) { _items.TryGetValue(itemId,out var item); if (item== null) throw new PSStorageException(PSStorageException.ErrorCodes.PsStorageItemNotFound, itemId); return item; } /// public override bool ContainsItem(string itemId) { return _items.ContainsKey(itemId); } #endregion } }