protected override void ProcessItem(Study study) { var result = EventResult.Success; try { WorkItem item; using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { item = ProcessStudy(study.Oid, context); context.Commit(); } if (item != null) { WorkItemPublishSubscribeHelper.PublishWorkItemChanged(WorkItemsChangedEventType.Update, WorkItemDataHelper.FromWorkItem(item)); } } catch (Exception) { result = EventResult.MajorFailure; throw; } finally { var instances = new AuditedInstances(); instances.AddInstance(study.PatientId, study.PatientsName, study.StudyInstanceUid); AuditHelper.LogDeleteStudies(AuditHelper.LocalAETitle, instances, EventSource.CurrentUser, result); } }
private void Publish(bool saveToDatabase) { if (saveToDatabase) { try { using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { var broker = context.GetWorkItemBroker(); Item = broker.GetWorkItem(Item.Oid); Item.Progress = Progress; context.Commit(); } } catch (Exception) { // Saw ChangeCOnflictException here a few times } } else { Item.Progress = Progress; } WorkItemPublishSubscribeHelper.PublishWorkItemChanged(WorkItemsChangedEventType.Update, WorkItemDataHelper.FromWorkItem(Item)); }
public void Refresh(WorkItemRefreshRequest request) { ThreadPool.QueueUserWorkItem( delegate { try { using (var context = new DataAccessContext()) { var broker = context.GetWorkItemBroker(); var dbList = broker.GetWorkItems(null, null, null); // send in batches of 200 foreach (var batch in BatchItems(dbList, 200)) { WorkItemPublishSubscribeHelper.PublishWorkItemsChanged(WorkItemsChangedEventType.Refresh, batch.Select(WorkItemDataHelper.FromWorkItem).ToList()); } } } catch (Exception e) { var message = SR.ExceptionErrorProcessingRefresh; var exceptionMessage = String.Format("{0}\nDetail:{1}", message, e.Message); Platform.Log(LogLevel.Error, e, exceptionMessage); // Don't rethrow here, we're in a thread pool anyways. } }); }
public WorkItemInsertResponse Insert(WorkItemInsertRequest request) { // TODO (CR Jun 2012): The fact that there is special processing in here for particular types of work items // indicates there is something wrong with the design that may make adding custom work item types difficult. // Maybe the different "processors" need to perform the insert, or at least have some kind of method (rule) // for processing the insert? var response = new WorkItemInsertResponse(); var now = DateTime.Now; var item = new Interface.WorkItem { Request = request.Request, Progress = request.Progress, Type = request.Request.WorkItemType, Priority = request.Request.Priority, ScheduledTime = now.AddSeconds(WorkItemServiceSettings.Default.InsertDelaySeconds), ProcessTime = now.AddSeconds(WorkItemServiceSettings.Default.InsertDelaySeconds), DeleteTime = now.AddMinutes(WorkItemServiceSettings.Default.DeleteDelayMinutes), ExpirationTime = now.AddSeconds(WorkItemServiceSettings.Default.ExpireDelaySeconds), RequestedTime = now, Status = WorkItemStatusEnum.Pending }; IoC.Get <IWorkItemOperation>().AddWorkItem(item); WorkItemPublishSubscribeHelper.PublishWorkItemChanged(WorkItemsChangedEventType.Update, response.Item); if (WorkItemProcessor.Instance != null) { WorkItemProcessor.Instance.SignalThread(); } return(response); }
/// <summary> /// Method for getting next <see cref="WorkItem"/> entry. /// </summary> /// <param name="count">The count.</param> /// <param name="priority">Search for stat items.</param> /// <remarks> /// </remarks> /// <returns> /// A <see cref="WorkItem"/> entry if found, or else null; /// </returns> private List <WorkItem> InternalGetWorkItems(int count, WorkItemPriorityEnum priority) { _nowRunningWorkItems.Clear(); _postponedWorkItems.Clear(); var itemsToPublish = new List <WorkItemData>(); try { var workItemBroker = _context.GetWorkItemBroker(); List <WorkItem> workItems = workItemBroker.GetWorkItemsForProcessing(count * 4, priority); foreach (var item in workItems) { string reason; if (CanStart(item, out reason)) { item.Status = WorkItemStatusEnum.InProgress; _nowRunningWorkItems.Add(item); } else { Postpone(item); _postponedWorkItems.Add(item); WorkItemProgress progress = item.Progress; if (progress != null) { progress.StatusDetails = reason; item.Progress = progress; itemsToPublish.Add(WorkItemDataHelper.FromWorkItem(item)); } } if (_nowRunningWorkItems.Count >= count) { break; } } _context.Commit(); return(new List <WorkItem>(_nowRunningWorkItems)); } catch (Exception x) { Platform.Log(LogLevel.Warn, x, "Unexpected error querying for {0} {1} priority WorkItems", count, priority.GetDescription()); return(null); } finally { if (itemsToPublish.Count > 0) { WorkItemPublishSubscribeHelper.PublishWorkItemsChanged(WorkItemsChangedEventType.Update, itemsToPublish); } } }
public void Dispose() { try { WorkItemPublishSubscribeHelper.Unsubscribe(_callback); } catch (Exception e) { Platform.Log(LogLevel.Error, e); } }
public WorkItemPublishResponse Publish(WorkItemPublishRequest request) { try { WorkItemPublishSubscribeHelper.PublishWorkItemChanged(WorkItemsChangedEventType.Update, request.Item); return(new WorkItemPublishResponse()); } catch (Exception e) { var message = "Failed to process WorkItem Publish request."; var exceptionMessage = String.Format("{0}\nDetail:{1}", message, e.Message); throw new WorkItemServiceException(exceptionMessage); } }
public WorkItemUnsubscribeResponse Unsubscribe(WorkItemUnsubscribeRequest request) { try { WorkItemPublishSubscribeHelper.Unsubscribe(_callback); return(new WorkItemUnsubscribeResponse()); } catch (Exception e) { var message = "Failed to process WorkItem Unsubscribe request."; var exceptionMessage = String.Format("{0}\nDetail:{1}", message, e.Message); throw new WorkItemServiceException(exceptionMessage); } }
public WorkItemSubscribeResponse Subscribe(WorkItemSubscribeRequest request) { try { WorkItemPublishSubscribeHelper.Subscribe(_callback); return(new WorkItemSubscribeResponse()); } catch (Exception e) { var message = SR.ExceptionErrorProcessingSubscribe; var exceptionMessage = String.Format("{0}\nDetail:{1}", message, e.Message); throw new WorkItemServiceException(exceptionMessage); } }
public override void Process() { if (CancelPending) { Proxy.Cancel(); return; } if (StopPending) { Proxy.Postpone(); return; } Progress.IsCancelable = true; Progress.Complete = false; Progress.StudiesToProcess = 0; Progress.TotalStudyFolders = 0; Progress.StudiesDeleted = 0; Progress.StudyFoldersProcessed = 0; Progress.StudiesProcessed = 0; Proxy.UpdateProgress(); _reindexUtility = new ReindexUtility(); _reindexUtility.Initialize(); try { WorkItemPublishSubscribeHelper.PublishStudiesCleared(); } catch (Exception e) { Platform.Log(LogLevel.Warn, e, "Unexpected error attempting to publish WorkItem StudiesCleared status"); } // Reset progress, in case of retry Progress.StudiesToProcess = _reindexUtility.DatabaseStudiesToScan; Progress.TotalStudyFolders = _reindexUtility.StudyFoldersToScan; Progress.StudiesDeleted = 0; Progress.StudyFoldersProcessed = 0; Progress.StudiesProcessed = 0; Progress.StudiesFailed = 0; Progress.Complete = false; Proxy.UpdateProgress(); _reindexUtility.StudyFolderProcessedEvent += delegate(object sender, ReindexUtility.StudyEventArgs e) { Progress.StudyFoldersProcessed++; Proxy.Item.StudyInstanceUid = e.StudyInstanceUid; Proxy.UpdateProgress(); }; _reindexUtility.StudyDeletedEvent += delegate(object sender, ReindexUtility.StudyEventArgs e) { Progress.StudiesDeleted++; Progress.StudiesProcessed++; Proxy.Item.StudyInstanceUid = e.StudyInstanceUid; Proxy.UpdateProgress(); }; _reindexUtility.StudyProcessedEvent += delegate(object sender, ReindexUtility.StudyEventArgs e) { Progress.StudiesProcessed++; Proxy.Item.StudyInstanceUid = e.StudyInstanceUid; Proxy.UpdateProgress(); }; _reindexUtility.StudiesRestoredEvent += delegate(object sender, ReindexUtility.StudiesEventArgs e) { foreach (var studyInstanceUid in e.StudyInstanceUids) { Proxy.Item.StudyInstanceUid = studyInstanceUid; Proxy.UpdateProgress(); } }; _reindexUtility.StudyReindexFailedEvent += delegate(object sender, ReindexUtility.StudyEventArgs e) { Progress.StudiesFailed++; Proxy.Item.StudyInstanceUid = e.StudyInstanceUid; if (!string.IsNullOrEmpty(e.Message)) { Progress.StatusDetails = e.Message; } Proxy.UpdateProgress(); }; _reindexUtility.Process(); if (StopPending) { Progress.Complete = true; Proxy.Postpone(); } else if (CancelPending) { Progress.Complete = true; Proxy.Cancel(); } else { Progress.Complete = true; if (Progress.StudiesFailed > 0) { Proxy.Fail(Progress.StatusDetails, WorkItemFailureType.Fatal); } else { Proxy.Complete(); } } }
public WorkItemUpdateResponse Update(WorkItemUpdateRequest request) { var response = new WorkItemUpdateResponse(); var workItem = IoC.Get <IWorkItemOperation>().GetWorkItem(request.Identifier); if (workItem == null) { response.Item = null; return(response); } var deleted = false; if (request.Delete.HasValue && request.Delete.Value) { if (workItem.Status != WorkItemStatusEnum.InProgress) { workItem.Status = WorkItemStatusEnum.Deleted; deleted = true; // If StudyDelete we're removing, "undelete" the study // CheckDeleteStudyCanceled(context, workItem); } } if (!deleted) { if (request.ExpirationTime.HasValue) { workItem.ExpirationTime = request.ExpirationTime.Value; } if (request.Priority.HasValue) { workItem.Priority = request.Priority.Value; } if (request.Status.HasValue && workItem.Status != WorkItemStatusEnum.InProgress) { workItem.Status = request.Status.Value; if (request.Status.Value == WorkItemStatusEnum.Canceled) { workItem.DeleteTime = DateTime.Now.AddMinutes(WorkItemServiceSettings.Default.DeleteDelayMinutes); } else if (request.Status.Value == WorkItemStatusEnum.Pending) { workItem.ScheduledTime = DateTime.Now; workItem.FailureCount = 0; } // Cache the UserIdentityContext for later use by the shred //if (workItem.Request.WorkItemType.Equals(ImportFilesRequest.WorkItemTypeString) && // request.Status.Value == WorkItemStatusEnum.Pending) // UserIdentityCache.Put(workItem.Oid, UserIdentityContext.CreateFromCurrentThreadPrincipal()); } if (request.ProcessTime.HasValue) { workItem.ProcessTime = request.ProcessTime.Value; } // Cancel if (request.Cancel.HasValue && request.Cancel.Value) { if (workItem.Progress == null || workItem.Progress.IsCancelable) { if (workItem.Status.Equals(WorkItemStatusEnum.Idle) || workItem.Status.Equals(WorkItemStatusEnum.Pending)) { workItem.Status = WorkItemStatusEnum.Canceled; // If StudyDelete we're removing, "undelete" the study // CheckDeleteStudyCanceled(context, workItem); } else if (workItem.Status.Equals(WorkItemStatusEnum.InProgress)) { // Abort the WorkItem WorkItemProcessor.Instance.Cancel(workItem.Oid); } } } // Pause if (request.Pause.HasValue && request.Pause.Value) { if (workItem.Progress == null || workItem.Progress.IsPauseable) { if (workItem.Status.Equals(WorkItemStatusEnum.Idle) || workItem.Status.Equals(WorkItemStatusEnum.Pending)) { workItem.Status = WorkItemStatusEnum.Pause; } else if (workItem.Status.Equals(WorkItemStatusEnum.InProgress)) { // Pause the WorkItem WorkItemProcessor.Instance.Pause(workItem.Oid); } } } IoC.Get <IWorkItemOperation>().SaveWorkItem(workItem); response.Item = WorkItemDataHelper.FromWorkItem(workItem); } WorkItemPublishSubscribeHelper.PublishWorkItemChanged(WorkItemsChangedEventType.Update, response.Item); return(response); }
public WorkItemInsertResponse Insert(WorkItemInsertRequest request) { // TODO (CR Jun 2012): The fact that there is special processing in here for particular types of work items // indicates there is something wrong with the design that may make adding custom work item types difficult. // Maybe the different "processors" need to perform the insert, or at least have some kind of method (rule) // for processing the insert? var response = new WorkItemInsertResponse(); using (var context = new DataAccessContext(DataAccessContext.WorkItemMutex)) { DateTime now = Platform.Time; var broker = context.GetWorkItemBroker(); if (request.Request.WorkItemType.Equals(ReindexRequest.WorkItemTypeString)) { var list = broker.GetWorkItems(request.Request.WorkItemType, null, null); foreach (var workItem in list) { if (workItem.Status == WorkItemStatusEnum.Pending || workItem.Status == WorkItemStatusEnum.InProgress) { response.Item = WorkItemDataHelper.FromWorkItem(workItem); return(response); } } } var deleteStudyRequest = request.Request as DeleteStudyRequest; if (deleteStudyRequest != null) { var list = broker.GetWorkItems(request.Request.WorkItemType, null, deleteStudyRequest.Study.StudyInstanceUid); foreach (var workItem in list) { if (workItem.Status == WorkItemStatusEnum.Pending || workItem.Status == WorkItemStatusEnum.InProgress) { // Mark studies to delete as "deleted" in the database. var studyBroker = context.GetStudyBroker(); var study = studyBroker.GetStudy(deleteStudyRequest.Study.StudyInstanceUid); if (study != null) { study.Deleted = true; context.Commit(); } response.Item = WorkItemDataHelper.FromWorkItem(workItem); return(response); } } } var item = new WorkItem { Request = request.Request, Progress = request.Progress, Type = request.Request.WorkItemType, Priority = request.Request.Priority, ScheduledTime = now.AddSeconds(WorkItemServiceSettings.Default.InsertDelaySeconds), ProcessTime = now.AddSeconds(WorkItemServiceSettings.Default.InsertDelaySeconds), DeleteTime = now.AddMinutes(WorkItemServiceSettings.Default.DeleteDelayMinutes), ExpirationTime = now.AddSeconds(WorkItemServiceSettings.Default.ExpireDelaySeconds), RequestedTime = now, Status = WorkItemStatusEnum.Pending }; var studyRequest = request.Request as WorkItemStudyRequest; if (studyRequest != null) { item.StudyInstanceUid = studyRequest.Study.StudyInstanceUid; if (request.Request.WorkItemType.Equals(DeleteStudyRequest.WorkItemTypeString)) { // Mark studies to delete as "deleted" in the database. var studyBroker = context.GetStudyBroker(); var study = studyBroker.GetStudy(studyRequest.Study.StudyInstanceUid); if (study != null) { study.Deleted = true; } } } broker.AddWorkItem(item); context.Commit(); response.Item = WorkItemDataHelper.FromWorkItem(item); } // Cache the UserIdentityContext for later use by the shred if (request.Request.WorkItemType.Equals(ImportFilesRequest.WorkItemTypeString)) { UserIdentityCache.Put(response.Item.Identifier, UserIdentityContext.CreateFromCurrentThreadPrincipal()); } WorkItemPublishSubscribeHelper.PublishWorkItemChanged(WorkItemsChangedEventType.Update, response.Item); if (WorkItemProcessor.Instance != null) { WorkItemProcessor.Instance.SignalThread(); } return(response); }