public async Task <Priority> CheckAndDelayOnWaitConditions(RoutedItem ri) { RoutedItemEx routedItem = (RoutedItemEx)ri; var taskInfo = $"task: {routedItem.TaskID}"; /* * check and delay on wait conditions * DICOM TAG (0000,0700) * LOW = 0002H * MEDIUM = 0000H * HIGH = 0001H */ //Engage: Waits get engaged when DICOM Priority Tag detected, and get disengaged when done ushort priority = 3; try { if (routedItem.sourceDicomFile != null) { DicomDataset dataSet = routedItem.sourceDicomFile.Dataset; string uuid = null; try { if (dataSet.Contains(DicomTag.StudyInstanceUID)) { uuid = dataSet.GetValue <string>(DicomTag.StudyInstanceUID, 0); } } catch (DicomDataException e) { _logger.Log(LogLevel.Debug, $"{taskInfo} {uuid} has no StudyInstanceUID field. {e.Message} {e.StackTrace}"); } Profile currentProfile = _profileStorage.Current; try { if (dataSet.Contains(DicomTag.Priority)) { priority = dataSet.GetValue <ushort>(DicomTag.Priority, 0); } else { _logger.Log(LogLevel.Debug, $"{taskInfo} {uuid} has no priority field."); } } catch (DicomDataException e) { _logger.Log(LogLevel.Debug, $"{taskInfo} {uuid} has no priority field. {e.Message} {e.StackTrace}"); } if (priority < 3) { _logger.Log(LogLevel.Information, $"{taskInfo} {uuid} has priority {priority}."); if (priority.Equals(0x01)) { currentProfile.highWait = true; _logger.Log(LogLevel.Information, $"{taskInfo} {uuid} with high priority detected. Setting highWait flag."); } if (priority.Equals(0x00)) { currentProfile.mediumWait = true; _logger.Log(LogLevel.Information, $"{taskInfo} {uuid} with medium priority detected. Setting highWait flag."); } } //Wait on Condition: if (currentProfile.highWait || currentProfile.mediumWait) { //something important is in mid transfer so check and wait if med or low if (priority < 3 || priority.Equals(0x02)) { //low or no priority is subject to both highWait and mediumWait conditions if (currentProfile.highWait && !priority.Equals(0x01)) { _logger.Log(LogLevel.Information, $"{taskInfo} highWait causing {currentProfile.highWaitDelay}ms delay for DICOM {uuid} in thread:{System.Threading.Thread.CurrentThread}."); await Task.Delay(currentProfile.highWaitDelay, _taskManager.cts.Token).ConfigureAwait(false); } if (currentProfile.mediumWait && !priority.Equals(0x00) && !priority.Equals(0x01)) { _logger.Log(LogLevel.Information, $"{taskInfo} mediumWait causing {currentProfile.mediumWaitDelay}ms delay for DICOM {uuid} in thread:{System.Threading.Thread.CurrentThread}."); await Task.Delay(currentProfile.mediumWaitDelay, _taskManager.cts.Token).ConfigureAwait(false); } } else if (priority.Equals(0x00)) { //medium priority is subject to only highWait conditions if (currentProfile.highWait) { _logger.Log(LogLevel.Information, $"{taskInfo} highWait causing {currentProfile.highWaitDelay}ms delay for DICOM {uuid} in thread:{System.Threading.Thread.CurrentThread}."); await Task.Delay(currentProfile.highWaitDelay, _taskManager.cts.Token).ConfigureAwait(false); } } } } } catch (TaskCanceledException) { _logger.Log(LogLevel.Information, $"Task was canceled."); } catch (Exception e) { _logger.LogFullException(e); } return(_util.GetPriority(priority)); }
/// Responds to a cstore request, which kicks off a StreamToRules task public DicomCStoreResponse OnCStoreRequest(DicomCStoreRequest request) { var taskID = _taskManager.NewTaskID(); var taskInfo = $"task: {taskID} messageID: {request.MessageID} connection: {((DICOMConnection)(base.UserState)).name}"; try { var fromConnection = _connectionFinder.GetDicomConnectionToLocalAETitle(_profileStorage.Current, Association.CalledAE); if (fromConnection == null) { //We have an inbound Association.CalledAE that we aren't configured for logger.Log(LogLevel.Warning, $"{taskInfo} There is no connection defined where the LocalAETitle matches the Association.CalledAE: {Association.CalledAE}"); return(new DicomCStoreResponse(request, DicomStatus.ProcessingFailure)); } logger.Log(LogLevel.Information, $"{taskInfo} CStoreRequest from {fromConnection.name}"); var conn = ((DICOMConnection)(base.UserState)); // var dir = profile.tempPath + Path.DirectorySeparatorChar + ((DICOMConnection)(base.UserState)).name + Path.DirectorySeparatorChar + "toRules"; // Directory.CreateDirectory(dir); // var filename = dir + Path.DirectorySeparatorChar + System.Guid.NewGuid(); // LifeImageLite.Logger.logger.Log(TraceEventType.Verbose, $"{taskInfo} Moving from {request.File.File.Name} to {filename}"); // request.File.File.Move(dstFileName: filename); RoutedItem routedItem = new RoutedItem( fromConnection: fromConnection.name, sourceFileName: request.File.File.Name, taskID: taskID) { type = RoutedItem.Type.DICOM }; request.Dataset.TryGetValue <string>(DicomTag.PatientID, 0, out routedItem.PatientID); request.Dataset.TryGetValue <string>(DicomTag.AccessionNumber, 0, out routedItem.AccessionNumber); request.Dataset.TryGetValue <string>(DicomTag.StudyInstanceUID, 0, out routedItem.Study); request.Dataset.TryGetValue <string>(DicomTag.StudyID, 0, out routedItem.StudyID); foreach (var item in request.Command) { logger.Log(LogLevel.Debug, $"Command tag: {item.Tag} value: {item.ValueRepresentation}"); } routedItem.id = $"PID:{routedItem.PatientID}, AN:{routedItem.AccessionNumber}"; // , UID:{routedItem.Study}"; //profile.rules.SendToRules(routedItem).Wait(); routedItem.priority = _util.GetPriority((ushort)request.Priority); _routedItemManager.Init(routedItem); _routedItemManager.Enqueue(conn, conn.toRules, nameof(conn.toRules), copy: true); DicomStatus status = DicomStatus.Success; DicomCStoreResponse response = new DicomCStoreResponse(request, status) { //Dataset = request.Dataset }; response.Command.AddOrUpdate(DicomTag.AffectedSOPInstanceUID, request.Dataset.GetValue <string>(DicomTag.SOPInstanceUID, 0)); response.Command.AddOrUpdate(DicomTag.AffectedSOPClassUID, request.Dataset.GetValue <string>(DicomTag.SOPClassUID, 0)); return(response); } catch (Exception e) { logger.Log(LogLevel.Critical, $"{taskInfo} {e.Message} {e.StackTrace}"); if (e.InnerException != null) { logger.Log(LogLevel.Critical, $"Inner Exception: {e.InnerException}"); } request.Dataset.AddOrUpdate(DicomTag.AffectedSOPInstanceUID, request.Dataset.GetValue <string>(DicomTag.SOPInstanceUID, 0)); return(new DicomCStoreResponse(request, new DicomStatus(DicomStatus.ProcessingFailure, $"CStore Response Exception: {e.Message} {e.StackTrace}"))); //out of resources not much flexibility here } finally { } }