예제 #1
0
        /// <summary>
        /// Method called when a <see cref="WorkQueue"/> item completes.
        /// </summary>
        /// <param name="queueItem">The queue item completing.</param>
        private void QueueItemComplete(Model.WorkQueue queueItem)
        {
            lock (_syncLock)
            {
                if (queueItem.WorkQueuePriorityEnum.Equals(WorkQueuePriorityEnum.High))
                {
                    _highPriorityCount--;
                }

                if (queueItem.WorkQueuePriorityEnum.Equals(WorkQueuePriorityEnum.Stat))
                {
                    _highPriorityCount--;
                }

                WorkQueueTypeProperties prop = _workQueuePropList[queueItem.WorkQueueTypeEnum];
                if (prop.MemoryLimited)
                {
                    _memoryLimitedCount--;
                }

                _totalThreadCount--;

                foreach (WorkQueueThreadParameter queuedItem in _queuedItems)
                {
                    if (queuedItem.Item.Key.Equals(queueItem.Key))
                    {
                        _queuedItems.Remove(queuedItem);
                        break;
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Enqueue a WorkQueue entry for processing.
        /// </summary>
        /// <param name="processor"></param>
        /// <param name="item"></param>
        /// <param name="del"></param>
        public void Enqueue(IWorkQueueItemProcessor processor, Model.WorkQueue item, WorkQueueThreadDelegate del)
        {
            WorkQueueThreadParameter parameter = new WorkQueueThreadParameter(processor, item, del);

            lock (_syncLock)
            {
                if (item.WorkQueuePriorityEnum.Equals(WorkQueuePriorityEnum.High))
                {
                    _highPriorityCount++;
                }
                if (item.WorkQueuePriorityEnum.Equals(WorkQueuePriorityEnum.Stat))
                {
                    _highPriorityCount++;
                }

                WorkQueueTypeProperties prop = _workQueuePropList[item.WorkQueueTypeEnum];
                if (prop.MemoryLimited)
                {
                    _memoryLimitedCount++;
                }

                _totalThreadCount++;

                _queuedItems.Add(parameter);
            }

            Enqueue(parameter, delegate(WorkQueueThreadParameter threadParameter)
            {
                threadParameter.Delegate(threadParameter.Processor, threadParameter.Item);

                QueueItemComplete(threadParameter.Item);
            });
        }
예제 #3
0
        public void RaiseAlert(Model.WorkQueue queueItem, AlertLevel level, string message)
        {
            WorkQueueTypeProperties prop = _propertiesDictionary[queueItem.WorkQueueTypeEnum];

            if (prop.AlertFailedWorkQueue || level == AlertLevel.Critical)
            {
                ServerPlatform.Alert(AlertCategory.Application, level,
                                     queueItem.WorkQueueTypeEnum.ToString(), AlertTypeCodes.UnableToProcess,
                                     GetWorkQueueContextData(queueItem), TimeSpan.Zero,
                                     "Work Queue item failed: Type={0}, GUID={1}: {2}",
                                     queueItem.WorkQueueTypeEnum,
                                     queueItem.GetKey(), message);
            }
        }
예제 #4
0
        /// <summary>
        /// Insert an EditStudy request.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="studyStorageKey"></param>
        /// <param name="serverPartitionKey"></param>
        /// <param name="type"></param>
        /// <param name="updateItems"></param>
        /// <param name="reason"></param>
        /// <param name="user"></param>
        /// <param name="editType"></param>
        /// <param name="priorityEnum">Optional parameter to set the priority of resultant <see cref="WorkQueue"/> items.</param>
        /// <returns></returns>
        private static WorkQueue InsertExternalEditStudyRequest(IUpdateContext context, ServerEntityKey studyStorageKey, ServerEntityKey serverPartitionKey,
                                                                WorkQueueTypeEnum type, List <UpdateItem> updateItems, string reason, string user, EditType editType, WorkQueuePriorityEnum priorityEnum = null)
        {
            var propertiesBroker = context.GetBroker <IWorkQueueTypePropertiesEntityBroker>();
            var criteria         = new WorkQueueTypePropertiesSelectCriteria();

            criteria.WorkQueueTypeEnum.EqualTo(type);
            WorkQueueTypeProperties properties = propertiesBroker.FindOne(criteria);

            var      broker = context.GetBroker <IWorkQueueEntityBroker>();
            var      insert = new WorkQueueUpdateColumns();
            DateTime now    = Platform.Time;
            var      data   = new EditStudyWorkQueueData
            {
                EditRequest =
                {
                    TimeStamp     = now,
                    UserId        = user,
                    UpdateEntries = updateItems,
                    Reason        = reason,
                    EditType      = editType
                }
            };

            insert.WorkQueueTypeEnum     = type;
            insert.StudyStorageKey       = studyStorageKey;
            insert.ServerPartitionKey    = serverPartitionKey;
            insert.ScheduledTime         = now;
            insert.ExpirationTime        = now.AddSeconds(properties.ExpireDelaySeconds);
            insert.WorkQueueStatusEnum   = WorkQueueStatusEnum.Pending;
            insert.WorkQueuePriorityEnum = priorityEnum ?? properties.WorkQueuePriorityEnum;
            insert.Data = XmlUtils.SerializeAsXmlDoc(data);
            WorkQueue editEntry = broker.Insert(insert);

            if (editEntry == null)
            {
                throw new ApplicationException(string.Format("Unable to insert an Edit request of type {0} for study for user {1}", type.Description, user));
            }
            return(editEntry);
        }
예제 #5
0
        /// <summary>
        /// Simple routine for failing a work queue item.
        /// </summary>
        /// <param name="item">The item to fail.</param>
        /// <param name="failureDescription">The reason for the failure.</param>
        private void FailQueueItem(Model.WorkQueue item, string failureDescription)
        {
            // Must retry to reset the status of the entry in case of db error
            // Failure to do so will create stale work queue entry (stuck in "In Progress" state)
            // which can only be recovered by restarting the service.
            while (true)
            {
                try
                {
                    WorkQueueTypeProperties prop = _propertiesDictionary[item.WorkQueueTypeEnum];
                    using (IUpdateContext updateContext = _store.OpenUpdateContext(UpdateContextSyncMode.Flush))
                    {
                        IUpdateWorkQueue          update = updateContext.GetBroker <IUpdateWorkQueue>();
                        UpdateWorkQueueParameters parms  = new UpdateWorkQueueParameters
                        {
                            ProcessorID        = ServerPlatform.ProcessorId,
                            WorkQueueKey       = item.GetKey(),
                            StudyStorageKey    = item.StudyStorageKey,
                            FailureCount       = item.FailureCount + 1,
                            FailureDescription = failureDescription
                        };

                        var settings = WorkQueueSettings.Instance;
                        if ((item.FailureCount + 1) > prop.MaxFailureCount)
                        {
                            Platform.Log(LogLevel.Error,
                                         "Failing {0} WorkQueue entry ({1}), reached max retry count of {2}. Failure Reason: {3}",
                                         item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1, failureDescription);
                            parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Failed;
                            parms.ScheduledTime       = Platform.Time;
                            parms.ExpirationTime      = Platform.Time.AddDays(1);

                            OnWorkQueueEntryFailed(item, failureDescription);
                        }
                        else
                        {
                            Platform.Log(LogLevel.Error,
                                         "Resetting {0} WorkQueue entry ({1}) to Pending, current retry count {2}. Failure Reason: {3}",
                                         item.WorkQueueTypeEnum, item.GetKey(), item.FailureCount + 1, failureDescription);
                            parms.WorkQueueStatusEnum = WorkQueueStatusEnum.Pending;
                            parms.ScheduledTime       = Platform.Time.AddMilliseconds(settings.WorkQueueQueryDelay);
                            parms.ExpirationTime      =
                                Platform.Time.AddSeconds((prop.MaxFailureCount - item.FailureCount) *
                                                         prop.FailureDelaySeconds);
                        }

                        if (false == update.Execute(parms))
                        {
                            Platform.Log(LogLevel.Error, "Unable to update {0} WorkQueue GUID: {1}", item.WorkQueueTypeEnum,
                                         item.GetKey().ToString());
                        }
                        else
                        {
                            updateContext.Commit();
                            break; // done
                        }
                    }
                }
                catch (Exception ex)
                {
                    Platform.Log(LogLevel.Error, "Error occurred when calling FailQueueItem. Retry later. {0}", ex.Message);
                    _terminateEvent.WaitOne(2000, false);
                    if (_stop)
                    {
                        Platform.Log(LogLevel.Warn, "Service is stopping. Retry to fail the entry is terminated.");
                        break;
                    }
                }
            }
        }