comparison OrthancServer/Sources/ServerIndex.cpp @ 4580:49f6b9a2b9f5 db-changes

remove the only use of GlobalProperty_FlushSleep
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 09 Mar 2021 14:49:39 +0100
parents 5ee9a4f8a0f0
children bb3c82b8f373
comparison
equal deleted inserted replaced
4579:5ee9a4f8a0f0 4580:49f6b9a2b9f5
451 } 451 }
452 }; 452 };
453 453
454 454
455 void ServerIndex::FlushThread(ServerIndex* that, 455 void ServerIndex::FlushThread(ServerIndex* that,
456 unsigned int threadSleep) 456 unsigned int threadSleepGranularityMilliseconds)
457 { 457 {
458 // By default, wait for 10 seconds before flushing 458 // By default, wait for 10 seconds before flushing
459 unsigned int sleep = 10; 459 static const unsigned int SLEEP_SECONDS = 10;
460 460
461 // TODO - REMOVE THIS 461 if (threadSleepGranularityMilliseconds > 1000)
462 try 462 {
463 { 463 throw OrthancException(ErrorCode_ParameterOutOfRange);
464 boost::mutex::scoped_lock lock(that->monitoringMutex_); 464 }
465 std::string sleepString; 465
466 466 LOG(INFO) << "Starting the database flushing thread (sleep = " << SLEEP_SECONDS << " seconds)";
467 if (that->db_.LookupGlobalProperty(sleepString, GlobalProperty_FlushSleep) &&
468 Toolbox::IsInteger(sleepString))
469 {
470 sleep = boost::lexical_cast<unsigned int>(sleepString);
471 }
472 }
473 catch (boost::bad_lexical_cast&)
474 {
475 }
476
477 LOG(INFO) << "Starting the database flushing thread (sleep = " << sleep << ")";
478 467
479 unsigned int count = 0; 468 unsigned int count = 0;
469 unsigned int countThreshold = (1000 * SLEEP_SECONDS) / threadSleepGranularityMilliseconds;
480 470
481 while (!that->done_) 471 while (!that->done_)
482 { 472 {
483 boost::this_thread::sleep(boost::posix_time::milliseconds(threadSleep)); 473 boost::this_thread::sleep(boost::posix_time::milliseconds(threadSleepGranularityMilliseconds));
484 count++; 474 count++;
485 if (count < sleep) 475
486 { 476 if (count >= countThreshold)
487 continue; 477 {
488 } 478 Logging::Flush();
489 479
490 Logging::Flush(); 480 boost::mutex::scoped_lock lock(that->monitoringMutex_);
491 481
492 boost::mutex::scoped_lock lock(that->monitoringMutex_); 482 try
493 483 {
494 try 484 that->db_.FlushToDisk();
495 { 485 }
496 that->db_.FlushToDisk(); 486 catch (OrthancException&)
497 } 487 {
498 catch (OrthancException&) 488 LOG(ERROR) << "Cannot flush the SQLite database to the disk (is your filesystem full?)";
499 { 489 }
500 LOG(ERROR) << "Cannot flush the SQLite database to the disk (is your filesystem full?)"; 490
501 } 491 count = 0;
502 492 }
503 count = 0;
504 } 493 }
505 494
506 LOG(INFO) << "Stopping the database flushing thread"; 495 LOG(INFO) << "Stopping the database flushing thread";
507 }
508
509
510 static bool ComputeExpectedNumberOfInstances(int64_t& target,
511 const DicomMap& dicomSummary)
512 {
513 try
514 {
515 const DicomValue* value;
516 const DicomValue* value2;
517
518 if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGES_IN_ACQUISITION)) != NULL &&
519 !value->IsNull() &&
520 !value->IsBinary() &&
521 (value2 = dicomSummary.TestAndGetValue(DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS)) != NULL &&
522 !value2->IsNull() &&
523 !value2->IsBinary())
524 {
525 // Patch for series with temporal positions thanks to Will Ryder
526 int64_t imagesInAcquisition = boost::lexical_cast<int64_t>(value->GetContent());
527 int64_t countTemporalPositions = boost::lexical_cast<int64_t>(value2->GetContent());
528 target = imagesInAcquisition * countTemporalPositions;
529 return (target > 0);
530 }
531
532 else if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_NUMBER_OF_SLICES)) != NULL &&
533 !value->IsNull() &&
534 !value->IsBinary() &&
535 (value2 = dicomSummary.TestAndGetValue(DICOM_TAG_NUMBER_OF_TIME_SLICES)) != NULL &&
536 !value2->IsBinary() &&
537 !value2->IsNull())
538 {
539 // Support of Cardio-PET images
540 int64_t numberOfSlices = boost::lexical_cast<int64_t>(value->GetContent());
541 int64_t numberOfTimeSlices = boost::lexical_cast<int64_t>(value2->GetContent());
542 target = numberOfSlices * numberOfTimeSlices;
543 return (target > 0);
544 }
545
546 else if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES)) != NULL &&
547 !value->IsNull() &&
548 !value->IsBinary())
549 {
550 target = boost::lexical_cast<int64_t>(value->GetContent());
551 return (target > 0);
552 }
553 }
554 catch (OrthancException&)
555 {
556 }
557 catch (boost::bad_lexical_cast&)
558 {
559 }
560
561 return false;
562 }
563
564
565
566
567 static bool LookupStringMetadata(std::string& result,
568 const std::map<MetadataType, std::string>& metadata,
569 MetadataType type)
570 {
571 std::map<MetadataType, std::string>::const_iterator found = metadata.find(type);
572
573 if (found == metadata.end())
574 {
575 return false;
576 }
577 else
578 {
579 result = found->second;
580 return true;
581 }
582 }
583
584
585 static bool LookupIntegerMetadata(int64_t& result,
586 const std::map<MetadataType, std::string>& metadata,
587 MetadataType type)
588 {
589 std::string s;
590 if (!LookupStringMetadata(s, metadata, type))
591 {
592 return false;
593 }
594
595 try
596 {
597 result = boost::lexical_cast<int64_t>(s);
598 return true;
599 }
600 catch (boost::bad_lexical_cast&)
601 {
602 return false;
603 }
604 } 496 }
605 497
606 498
607 void ServerIndex::LogChange(int64_t internalId, 499 void ServerIndex::LogChange(int64_t internalId,
608 ChangeType changeType, 500 ChangeType changeType,
627 } 519 }
628 520
629 521
630 ServerIndex::ServerIndex(ServerContext& context, 522 ServerIndex::ServerIndex(ServerContext& context,
631 IDatabaseWrapper& db, 523 IDatabaseWrapper& db,
632 unsigned int threadSleep) : 524 unsigned int threadSleepGranularityMilliseconds) :
633 done_(false), 525 done_(false),
634 db_(db), 526 db_(db),
635 maximumStorageSize_(0), 527 maximumStorageSize_(0),
636 maximumPatients_(0), 528 maximumPatients_(0),
637 mainDicomTagsRegistry_(new MainDicomTagsRegistry), 529 mainDicomTagsRegistry_(new MainDicomTagsRegistry),
644 // execution of Orthanc 536 // execution of Orthanc
645 StandaloneRecycling(maximumStorageSize_, maximumPatients_); 537 StandaloneRecycling(maximumStorageSize_, maximumPatients_);
646 538
647 if (db.HasFlushToDisk()) 539 if (db.HasFlushToDisk())
648 { 540 {
649 flushThread_ = boost::thread(FlushThread, this, threadSleep); 541 flushThread_ = boost::thread(FlushThread, this, threadSleepGranularityMilliseconds);
650 } 542 }
651 543
652 unstableResourcesMonitorThread_ = boost::thread 544 unstableResourcesMonitorThread_ = boost::thread
653 (UnstableResourcesMonitorThread, this, threadSleep); 545 (UnstableResourcesMonitorThread, this, threadSleepGranularityMilliseconds);
654 } 546 }
655 547
656 548
657 549
658 ServerIndex::~ServerIndex() 550 ServerIndex::~ServerIndex()
839 StandaloneRecycling(maximumStorageSize_, maximumPatients_); 731 StandaloneRecycling(maximumStorageSize_, maximumPatients_);
840 } 732 }
841 733
842 734
843 void ServerIndex::UnstableResourcesMonitorThread(ServerIndex* that, 735 void ServerIndex::UnstableResourcesMonitorThread(ServerIndex* that,
844 unsigned int threadSleep) 736 unsigned int threadSleepGranularityMilliseconds)
845 { 737 {
846 int stableAge; 738 int stableAge;
847 739
848 { 740 {
849 OrthancConfiguration::ReaderLock lock; 741 OrthancConfiguration::ReaderLock lock;
858 LOG(INFO) << "Starting the monitor for stable resources (stable age = " << stableAge << ")"; 750 LOG(INFO) << "Starting the monitor for stable resources (stable age = " << stableAge << ")";
859 751
860 while (!that->done_) 752 while (!that->done_)
861 { 753 {
862 // Check for stable resources each few seconds 754 // Check for stable resources each few seconds
863 boost::this_thread::sleep(boost::posix_time::milliseconds(threadSleep)); 755 boost::this_thread::sleep(boost::posix_time::milliseconds(threadSleepGranularityMilliseconds));
864 756
865 boost::mutex::scoped_lock lock(that->monitoringMutex_); 757 boost::mutex::scoped_lock lock(that->monitoringMutex_);
866 758
867 while (!that->unstableResources_.IsEmpty() && 759 while (!that->unstableResources_.IsEmpty() &&
868 that->unstableResources_.GetOldestPayload().GetAge() > static_cast<unsigned int>(stableAge)) 760 that->unstableResources_.GetOldestPayload().GetAge() > static_cast<unsigned int>(stableAge))
1260 { 1152 {
1261 class Operations : public ReadOnlyOperationsT4<bool&, Json::Value&, const std::string&, ResourceType> 1153 class Operations : public ReadOnlyOperationsT4<bool&, Json::Value&, const std::string&, ResourceType>
1262 { 1154 {
1263 private: 1155 private:
1264 ServerIndex& index_; // TODO - REMOVE 1156 ServerIndex& index_; // TODO - REMOVE
1157
1158 static bool LookupStringMetadata(std::string& result,
1159 const std::map<MetadataType, std::string>& metadata,
1160 MetadataType type)
1161 {
1162 std::map<MetadataType, std::string>::const_iterator found = metadata.find(type);
1163
1164 if (found == metadata.end())
1165 {
1166 return false;
1167 }
1168 else
1169 {
1170 result = found->second;
1171 return true;
1172 }
1173 }
1174
1175
1176 static bool LookupIntegerMetadata(int64_t& result,
1177 const std::map<MetadataType, std::string>& metadata,
1178 MetadataType type)
1179 {
1180 std::string s;
1181 if (!LookupStringMetadata(s, metadata, type))
1182 {
1183 return false;
1184 }
1185
1186 try
1187 {
1188 result = boost::lexical_cast<int64_t>(s);
1189 return true;
1190 }
1191 catch (boost::bad_lexical_cast&)
1192 {
1193 return false;
1194 }
1195 }
1196
1265 1197
1266 public: 1198 public:
1267 explicit Operations(ServerIndex& index) : 1199 explicit Operations(ServerIndex& index) :
1268 index_(index) 1200 index_(index)
1269 { 1201 {
3215 std::string hashPatient_; 3147 std::string hashPatient_;
3216 std::string hashStudy_; 3148 std::string hashStudy_;
3217 std::string hashSeries_; 3149 std::string hashSeries_;
3218 std::string hashInstance_; 3150 std::string hashInstance_;
3219 3151
3152 static bool ComputeExpectedNumberOfInstances(int64_t& target,
3153 const DicomMap& dicomSummary)
3154 {
3155 try
3156 {
3157 const DicomValue* value;
3158 const DicomValue* value2;
3159
3160 if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGES_IN_ACQUISITION)) != NULL &&
3161 !value->IsNull() &&
3162 !value->IsBinary() &&
3163 (value2 = dicomSummary.TestAndGetValue(DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS)) != NULL &&
3164 !value2->IsNull() &&
3165 !value2->IsBinary())
3166 {
3167 // Patch for series with temporal positions thanks to Will Ryder
3168 int64_t imagesInAcquisition = boost::lexical_cast<int64_t>(value->GetContent());
3169 int64_t countTemporalPositions = boost::lexical_cast<int64_t>(value2->GetContent());
3170 target = imagesInAcquisition * countTemporalPositions;
3171 return (target > 0);
3172 }
3173
3174 else if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_NUMBER_OF_SLICES)) != NULL &&
3175 !value->IsNull() &&
3176 !value->IsBinary() &&
3177 (value2 = dicomSummary.TestAndGetValue(DICOM_TAG_NUMBER_OF_TIME_SLICES)) != NULL &&
3178 !value2->IsBinary() &&
3179 !value2->IsNull())
3180 {
3181 // Support of Cardio-PET images
3182 int64_t numberOfSlices = boost::lexical_cast<int64_t>(value->GetContent());
3183 int64_t numberOfTimeSlices = boost::lexical_cast<int64_t>(value2->GetContent());
3184 target = numberOfSlices * numberOfTimeSlices;
3185 return (target > 0);
3186 }
3187
3188 else if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES)) != NULL &&
3189 !value->IsNull() &&
3190 !value->IsBinary())
3191 {
3192 target = boost::lexical_cast<int64_t>(value->GetContent());
3193 return (target > 0);
3194 }
3195 }
3196 catch (OrthancException&)
3197 {
3198 }
3199 catch (boost::bad_lexical_cast&)
3200 {
3201 }
3202
3203 return false;
3204 }
3205
3220 public: 3206 public:
3221 Operations(std::map<MetadataType, std::string>& instanceMetadata, 3207 Operations(std::map<MetadataType, std::string>& instanceMetadata,
3222 ServerIndex& index, 3208 ServerIndex& index,
3223 const DicomMap& dicomSummary, 3209 const DicomMap& dicomSummary,
3224 const Attachments& attachments, 3210 const Attachments& attachments,