コード例 #1
0
        protected override void ProcessMessageImpl(IMessageHeader header, DicomFileMessage message, ulong tag)
        {
            DicomDataset dataset;

            try
            {
                dataset = DicomTypeTranslater.DeserializeJsonToDataset(message.DicomDataset);
            }
            catch (Exception e)
            {
                ErrorAndNack(header, tag, "Could not rebuild DicomDataset from message", e);
                return;
            }

            var toQueue = new QueuedImage(header, tag, message, dataset);

            lock (_oQueueLock)
                _imageQueue.Enqueue(toQueue);
        }
コード例 #2
0
        private void RunDleIfRequired()
        {
            //if there are a decent number ready to go or we haven't run in a while (and there is at least 1)
            if (GetQueueCount() < (DateTime.Now.Subtract(_lastRanDle) > _maximumRunDelayInSeconds ? 1 : _minimumBatchSize))
            {
                return;
            }

            var toProcess  = new List <QueuedImage>();
            var duplicates = new List <QueuedImage>();
            var seenSoFar  = new HashSet <string>();

            // Get the messages we will start this DLE with, accounting for duplicates
            lock (_oQueueLock)
            {
                while (_imageQueue.Count > 0)
                {
                    QueuedImage queuedImage = _imageQueue.Dequeue();

                    if (seenSoFar.Contains(queuedImage.DicomFileMessage.DicomDataset))
                    {
                        duplicates.Add(queuedImage);
                    }
                    else
                    {
                        toProcess.Add(queuedImage);
                        seenSoFar.Add(queuedImage.DicomFileMessage.DicomDataset);
                    }
                }
            }

            //All messages were rejected
            if (!toProcess.Any())
            {
                return;
            }

            if (duplicates.Any())
            {
                Logger.Log(LogLevel.Warn, "Acking " + duplicates.Count + " duplicate Datasets");
                duplicates.ForEach(x => Ack(x.Header, x.tag));
            }

            var parallelDleHost = new ParallelDLEHost(_repositoryLocator, DatabaseNamer, _useInsertIntoForRawMigration);

            Logger.Info("Starting DLE with " + toProcess.Count + " messages");

            if (RunChecks)
            {
                RunDleChecks();
            }

            int       remainingRetries = _retryOnFailureCount;
            Exception firstException   = null;

            ExitCodeType exitCode;

            var datasetProvider = new DicomFileMessageToDatasetListWorklist(toProcess);

            do
            {
                Logger.Debug("Starting a ParallelDLEHost");

                // We last ran now!
                _lastRanDle = DateTime.Now;

                //reset the progress e.g. if we crashed later on in the load
                datasetProvider.ResetProgress();

                try
                {
                    exitCode = parallelDleHost.RunDLE(_lmd, datasetProvider);
                }
                catch (Exception e)
                {
                    Logger.Debug(e, "ParallelDLEHost threw exception of type " + e.GetType());
                    _dleExceptions.Add(e);
                    exitCode = ExitCodeType.Error;

                    if (remainingRetries > 0)
                    {
                        //wait a random length of time averaging the _retryDelayInSeconds to avoid retrying at the same time as other processes
                        //where there is resource contention that results in simultaneous failures.
                        var r    = new Random();
                        var wait = r.Next(_retryDelayInSeconds * 2);

                        Logger.Info("Sleeping " + wait + "s after failure");
                        Task.Delay(new TimeSpan(0, 0, 0, wait)).Wait();

                        if (RunChecks)
                        {
                            Logger.Warn(e, "Running checks before we retry");
                            RunDleChecks();
                        }
                    }

                    firstException = firstException ?? e;
                }
            }while (remainingRetries-- > 0 && (exitCode == ExitCodeType.Error || exitCode == ExitCodeType.Abort));

            Logger.Info("DLE exited with code " + exitCode);

            switch (exitCode)
            {
            case ExitCodeType.Success:
            case ExitCodeType.OperationNotRequired:
            {
                foreach (QueuedImage corrupt in datasetProvider.CorruptMessages)
                {
                    ErrorAndNack(corrupt.Header, corrupt.tag, "Nacking Corrupt image", null);
                }

                QueuedImage[] successes = toProcess.Except(datasetProvider.CorruptMessages).ToArray();

                Ack(successes.Select(x => x.Header).ToList(),
                    successes.Select(x => x.tag).Max(x => x));

                break;
            }

            case ExitCodeType.Error:
            case ExitCodeType.Abort:
            {
                _stopTokenSource.Cancel();
                Fatal("DLE Crashed " + (_retryOnFailureCount + 1) + " time(s) on the same batch", firstException);
                break;
            }

            default:
            {
                _stopTokenSource.Cancel();
                Fatal("No case for DLE exit code " + exitCode, null);
                break;
            }
            }
        }