/// <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; } } } }
/// <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); }); }
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); } }
/// <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); }
/// <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; } } } }