Beispiel #1
0
        /// <summary>
        /// Process study migration candidates retrieved from the <see cref="Model.FilesystemQueue"/> table
        /// </summary>
        /// <param name="candidateList">The list of candidate studies for deleting.</param>
        private void ProcessStudyMigrateCandidates(IList <FilesystemQueue> candidateList)
        {
            Platform.CheckForNullReference(candidateList, "candidateList");

            if (candidateList.Count > 0)
            {
                Platform.Log(LogLevel.Debug, "Scheduling tier-migration for {0} eligible studies...", candidateList.Count);
            }

            FilesystemProcessStatistics summaryStats = new FilesystemProcessStatistics("FilesystemTierMigrateInsert");

            foreach (FilesystemQueue queueItem in candidateList)
            {
                if (_bytesToRemove < 0 || CancelPending)
                {
                    Platform.Log(LogLevel.Debug, "Estimated disk space has been reached.");
                    break;
                }
                StudyProcessStatistics stats = new StudyProcessStatistics("TierMigrateStudy");
                stats.TotalTime.Start();

                stats.StudyStorageTime.Start();
                // First, get the StudyStorage locations for the study, and calculate the disk usage.
                StudyStorageLocation location;
                if (!FilesystemMonitor.Instance.GetWritableStudyStorageLocation(queueItem.StudyStorageKey, out location))
                {
                    continue;
                }
                stats.StudyStorageTime.End();

                stats.CalculateDirectorySizeTime.Start();
                // Get the disk usage
                float studySize = EstimateFolderSizeFromStudyXml(location);
                stats.CalculateDirectorySizeTime.End();
                stats.DirectorySize = (ulong)studySize;

                stats.DbUpdateTime.Start();
                using (
                    IUpdateContext update =
                        PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush))
                {
                    ILockStudy          lockstudy = update.GetBroker <ILockStudy>();
                    LockStudyParameters lockParms = new LockStudyParameters
                    {
                        StudyStorageKey     = location.Key,
                        QueueStudyStateEnum = QueueStudyStateEnum.MigrationScheduled
                    };
                    if (!lockstudy.Execute(lockParms) || !lockParms.Successful)
                    {
                        Platform.Log(LogLevel.Warn, "Unable to lock study for inserting Tier Migration. Reason:{0}. Skipping study ({1})",
                                     lockParms.FailureReason, location.StudyInstanceUid);
                        continue;
                    }

                    IInsertWorkQueueFromFilesystemQueue broker = update.GetBroker <IInsertWorkQueueFromFilesystemQueue>();

                    InsertWorkQueueFromFilesystemQueueParameters insertParms = new InsertWorkQueueFromFilesystemQueueParameters
                    {
                        StudyStorageKey         = location.GetKey(),
                        ServerPartitionKey      = location.ServerPartitionKey,
                        ScheduledTime           = _scheduledTime,
                        DeleteFilesystemQueue   = true,
                        WorkQueueTypeEnum       = WorkQueueTypeEnum.MigrateStudy,
                        FilesystemQueueTypeEnum =
                            FilesystemQueueTypeEnum.TierMigrate
                    };

                    Platform.Log(LogLevel.Debug, "Scheduling tier-migration for study {0} from {1} at {2}...",
                                 location.StudyInstanceUid, location.FilesystemTierEnum, _scheduledTime);
                    WorkQueue insertItem = broker.FindOne(insertParms);
                    if (insertItem == null)
                    {
                        Platform.Log(LogLevel.Error,
                                     "Unexpected problem inserting 'MigrateStudy' record into WorkQueue for Study {0}",
                                     location.StudyInstanceUid);
                    }
                    else
                    {
                        update.Commit();
                        _bytesToRemove -= studySize;
                        _studiesMigrated++;

                        // spread out the scheduled migration entries based on the size
                        // assuming that the larger the study the longer it will take to migrate
                        // The assumed migration speed is arbitarily chosen.
                        double   migrationSpeed = ServiceLockSettings.Default.TierMigrationSpeed * 1024 * 1024;           // MB / sec
                        TimeSpan estMigrateTime = TimeSpan.FromSeconds(studySize / migrationSpeed);
                        _scheduledTime = _scheduledTime.Add(estMigrateTime);
                    }
                }
                stats.DbUpdateTime.End();
                stats.TotalTime.End();

                summaryStats.AddSubStats(stats);
                StatisticsLogger.Log(LogLevel.Debug, stats);
            }

            summaryStats.CalculateAverage();
            StatisticsLogger.Log(LogLevel.Info, false, summaryStats);
        }
        /// <summary>
        /// Process StudyCompress Candidates retrieved from the <see cref="Model.FilesystemQueue"/> table
        /// </summary>
        /// <param name="candidateList">The list of candidate studies for deleting.</param>
        /// <param name="type">The type of compress candidate (lossy or lossless)</param>
        private void ProcessCompressCandidates(IEnumerable <FilesystemQueue> candidateList, FilesystemQueueTypeEnum type)
        {
            using (ServerExecutionContext context = new ServerExecutionContext())
            {
                DateTime scheduledTime = Platform.Time.AddSeconds(10);

                foreach (FilesystemQueue queueItem in candidateList)
                {
                    // Check for Shutdown/Cancel
                    if (CancelPending)
                    {
                        break;
                    }

                    // First, get the StudyStorage locations for the study, and calculate the disk usage.
                    StudyStorageLocation location;
                    if (!FilesystemMonitor.Instance.GetWritableStudyStorageLocation(queueItem.StudyStorageKey, out location))
                    {
                        continue;
                    }

                    StudyXml studyXml;
                    try
                    {
                        studyXml = LoadStudyXml(location);
                    }
                    catch (Exception e)
                    {
                        Platform.Log(LogLevel.Error, e, "Skipping compress candidate, unexpected exception loading StudyXml file for {0}",
                                     location.GetStudyPath());
                        continue;
                    }

                    using (
                        IUpdateContext update = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush))
                    {
                        ILockStudy          lockstudy = update.GetBroker <ILockStudy>();
                        LockStudyParameters lockParms = new LockStudyParameters();
                        lockParms.StudyStorageKey     = location.Key;
                        lockParms.QueueStudyStateEnum = QueueStudyStateEnum.CompressScheduled;
                        if (!lockstudy.Execute(lockParms) || !lockParms.Successful)
                        {
                            Platform.Log(LogLevel.Warn,
                                         "Unable to lock study for inserting Lossless Compress. Reason:{0}. Skipping study ({1})",
                                         lockParms.FailureReason, location.StudyInstanceUid);
                            continue;
                        }

                        scheduledTime = scheduledTime.AddSeconds(3);

                        IInsertWorkQueueFromFilesystemQueue workQueueInsert = update.GetBroker <IInsertWorkQueueFromFilesystemQueue>();

                        InsertWorkQueueFromFilesystemQueueParameters insertParms = new InsertWorkQueueFromFilesystemQueueParameters();
                        insertParms.WorkQueueTypeEnum       = WorkQueueTypeEnum.CompressStudy;
                        insertParms.FilesystemQueueTypeEnum = FilesystemQueueTypeEnum.LosslessCompress;
                        insertParms.StudyStorageKey         = location.GetKey();
                        insertParms.ServerPartitionKey      = location.ServerPartitionKey;
                        DateTime expirationTime = scheduledTime;
                        insertParms.ScheduledTime         = expirationTime;
                        insertParms.DeleteFilesystemQueue = true;
                        insertParms.Data = queueItem.QueueXml;
                        insertParms.FilesystemQueueTypeEnum = type;
                        insertParms.WorkQueueTypeEnum       = WorkQueueTypeEnum.CompressStudy;

                        try
                        {
                            WorkQueue entry = workQueueInsert.FindOne(insertParms);

                            InsertWorkQueueUidFromStudyXml(studyXml, update, entry.GetKey());

                            update.Commit();
                            _studiesInserted++;
                        }
                        catch (Exception e)
                        {
                            Platform.Log(LogLevel.Error, e,
                                         "Skipping compress record, unexpected problem inserting 'CompressStudy' record into WorkQueue for Study {0}",
                                         location.StudyInstanceUid);
                            // throw; -- would cause abort of inserts, go ahead and try everything
                        }
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Process StudyPurge <see cref="FilesystemQueue"/> entries.
        /// </summary>
        /// <param name="candidateList">The list of candidates for purging</param>
        private void ProcessStudyPurgeCandidates(IList <FilesystemQueue> candidateList)
        {
            if (candidateList.Count > 0)
            {
                Platform.Log(LogLevel.Debug, "Scheduling purge study for {0} eligible studies...", candidateList.Count);
            }

            FilesystemProcessStatistics summaryStats = new FilesystemProcessStatistics("FilesystemPurgeInsert");

            foreach (FilesystemQueue queueItem in candidateList)
            {
                if (_bytesToRemove < 0 || CancelPending)
                {
                    break;
                }

                StudyProcessStatistics stats = new StudyProcessStatistics("PurgeStudy");
                stats.TotalTime.Start();

                stats.StudyStorageTime.Start();
                // First, get the StudyStorage locations for the study, and calculate the disk usage.
                StudyStorageLocation location;
                if (!FilesystemMonitor.Instance.GetWritableStudyStorageLocation(queueItem.StudyStorageKey, out location))
                {
                    continue;
                }
                stats.StudyStorageTime.End();

                stats.CalculateDirectorySizeTime.Start();
                // Get the disk usage
                float studySize = EstimateFolderSizeFromStudyXml(location);
                stats.CalculateDirectorySizeTime.End();
                stats.DirectorySize = (ulong)studySize;

                stats.DbUpdateTime.Start();
                // Update the DB
                using (
                    IUpdateContext update = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush))
                {
                    ILockStudy          lockstudy = update.GetBroker <ILockStudy>();
                    LockStudyParameters lockParms = new LockStudyParameters();
                    lockParms.StudyStorageKey     = location.Key;
                    lockParms.QueueStudyStateEnum = QueueStudyStateEnum.PurgeScheduled;
                    if (!lockstudy.Execute(lockParms) || !lockParms.Successful)
                    {
                        Platform.Log(LogLevel.Warn, "Unable to lock study for inserting Study Purge, skipping study ({0}",
                                     location.StudyInstanceUid);
                        continue;
                    }

                    IInsertWorkQueueFromFilesystemQueue insertBroker = update.GetBroker <IInsertWorkQueueFromFilesystemQueue>();

                    InsertWorkQueueFromFilesystemQueueParameters insertParms = new InsertWorkQueueFromFilesystemQueueParameters();
                    insertParms.StudyStorageKey         = location.GetKey();
                    insertParms.ServerPartitionKey      = location.ServerPartitionKey;
                    insertParms.ScheduledTime           = _scheduledTime;
                    insertParms.DeleteFilesystemQueue   = true;
                    insertParms.WorkQueueTypeEnum       = WorkQueueTypeEnum.PurgeStudy;
                    insertParms.FilesystemQueueTypeEnum = FilesystemQueueTypeEnum.PurgeStudy;

                    WorkQueue insertItem = insertBroker.FindOne(insertParms);
                    if (insertItem == null)
                    {
                        Platform.Log(LogLevel.Error, "Unexpected problem inserting 'PurgeStudy' record into WorkQueue for Study {0}",
                                     location.StudyInstanceUid);
                    }
                    else
                    {
                        update.Commit();
                        _bytesToRemove -= studySize;
                        _studiesPurged++;
                        _scheduledTime = _scheduledTime.AddSeconds(2);
                    }
                }
                stats.DbUpdateTime.End();
                stats.TotalTime.End();

                summaryStats.AddSubStats(stats);
                StatisticsLogger.Log(LogLevel.Debug, stats);
            }
            summaryStats.CalculateAverage();
            StatisticsLogger.Log(LogLevel.Info, false, summaryStats);
        }