Ejemplo n.º 1
0
        public async Task <IActionResult> Rollback(string transactionKey, string errorCode = null, string errorMessage = null, bool isFatal = false)
        {
            try
            {
                Guid      transactionKeyId = Guid.Parse(transactionKey);
                QueueItem queueItem        = await manager.GetQueueItem(transactionKeyId);

                if (queueItem == null)
                {
                    ModelState.AddModelError("Rollback", "Transaction key cannot be found.");
                    return(BadRequest(ModelState));
                }

                Guid  queueItemId = (Guid)queueItem.Id;
                Guid  queueId     = queueItem.QueueId;
                Queue queue       = queueRepository.GetOne(queueId);
                int   retryLimit  = queue.MaxRetryCount;

                if (retryLimit == null || retryLimit == 0)
                {
                    retryLimit = int.Parse(Configuration["Queue.Global:DefaultMaxRetryCount"]);
                }

                await manager.Rollback(queueItemId, transactionKeyId, retryLimit, errorCode, errorMessage, isFatal);

                return(Ok());
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("Rollback", ex.Message);
                return(BadRequest(ModelState));
            }
        }
        public Queue CheckReferentialIntegrity(string id)
        {
            Guid entityId      = new Guid(id);
            var  existingQueue = _queueRepo.GetOne(entityId);

            if (existingQueue == null)
            {
                throw new EntityDoesNotExistException("Queue could not be found");
            }

            var lockedQueueItems = _queueItemRepo.Find(0, 1).Items?
                                   .Where(q => q.QueueId == entityId && q.IsLocked);

            bool lockedChildExists = lockedQueueItems.Count() > 0;

            if (lockedChildExists)
            {
                throw new EntityOperationException("Referential integrity in queue items table; please remove any locked items associated with this queue first");
            }

            return(existingQueue);
        }
Ejemplo n.º 3
0
        public void SetNewState(QueueItem item)
        {
            item.RetryCount += 1;
            Guid  queueId    = item.QueueId;
            Queue queue      = queueRepository.GetOne(queueId);
            int   retryLimit = queue.MaxRetryCount;

            if (item.RetryCount < retryLimit)
            {
                item.State        = QueueItemStateType.New.ToString();
                item.StateMessage = $"Queue item {item.Name}'s lock time has expired and failed {item.RetryCount} time(s).  Adding back to queue and trying again.";
            }
            else
            {
                item.State        = QueueItemStateType.Failed.ToString();
                item.StateMessage = $"Queue item transaction {item.Name} failed fatally and was unable to be automated {retryLimit} times.";
            }
            item.IsLocked           = false;
            item.LockedBy           = null;
            item.LockedEndTimeUTC   = null;
            item.LockedUntilUTC     = null;
            item.LockTransactionKey = null;
        }
Ejemplo n.º 4
0
        public async Task <QueueItem> Rollback(Guid transactionKey, string errorCode = null, string errorMessage = null, bool isFatal = false)
        {
            QueueItem queueItem = await GetQueueItem(transactionKey);

            if (queueItem == null)
            {
                throw new EntityDoesNotExistException("Transaction key cannot be found");
            }

            Guid  queueItemId = queueItem.Id.Value;
            Guid  queueId     = queueItem.QueueId;
            Queue queue       = _queueRepository.GetOne(queueId);
            int   retryLimit  = queue.MaxRetryCount;

            if (retryLimit == null || retryLimit == 0)
            {
                retryLimit = int.Parse(Configuration["Queue.Global:DefaultMaxRetryCount"]);
            }

            var item = _repo.GetOne(queueItemId);

            if (item == null)
            {
                throw new EntityDoesNotExistException("QueueItem does not exist or you do not have authorized access.");
            }
            UpdateItemsStates(item.QueueId.ToString());

            if (item.State == "Failed")
            {
                throw new EntityOperationException(item.StateMessage);
            }

            if (item?.LockedUntilUTC < DateTime.UtcNow)
            {
                SetNewState(item);
                item.ErrorCode    = errorCode;
                item.ErrorMessage = errorMessage;
                Dictionary <string, string> error = new Dictionary <string, string>();
                if (!string.IsNullOrEmpty(errorCode))
                {
                    error.Add(errorCode, errorMessage);
                }
                item.ErrorSerialized = JsonConvert.SerializeObject(error);

                _repo.Update(item);
                return(item);
            }
            else if (item?.IsLocked == true && item?.LockedUntilUTC >= DateTime.UtcNow && item?.LockTransactionKey == transactionKey)
            {
                item.IsLocked           = false;
                item.LockTransactionKey = null;
                item.LockedEndTimeUTC   = DateTime.UtcNow;
                item.LockedBy           = null;
                item.LockedUntilUTC     = null;
                item.RetryCount        += 1;

                item.ErrorCode    = errorCode;
                item.ErrorMessage = errorMessage;
                Dictionary <string, string> error = new Dictionary <string, string>();
                if (!string.IsNullOrEmpty(errorCode))
                {
                    error.Add(errorCode, errorMessage);
                }
                item.ErrorSerialized = JsonConvert.SerializeObject(error);

                if (isFatal)
                {
                    item.State        = QueueItemStateType.Failed.ToString();
                    item.StateMessage = $"Queue item transaction {item.Name} has failed fatally.";
                }
                else
                {
                    if (item.RetryCount < retryLimit)
                    {
                        item.State        = QueueItemStateType.New.ToString();
                        item.StateMessage = $"Queue item transaction {item.Name} failed {item.RetryCount} time(s).  Adding back to queue and trying again.";
                    }
                    else
                    {
                        item.State        = QueueItemStateType.Failed.ToString();
                        item.StateMessage = $"Queue item transaction {item.Name} failed fatally and was unable to be automated {retryLimit} times.";
                    }
                }
                _repo.Update(item);
                return(item);
            }
            else
            {
                throw new Exception("Transaction key mismatched or expired. Cannot rollback.");
            }
        }