comparison OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp @ 4613:2684544ff03c db-changes

maximum number of database retries for writer collisions is now set by the plugins
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 08 Apr 2021 10:46:12 +0200
parents 4982733a4e39
children fda80844b920
comparison
equal deleted inserted replaced
4612:4982733a4e39 4613:2684544ff03c
586 586
587 587
588 void StatelessDatabaseOperations::ApplyInternal(IReadOnlyOperations* readOperations, 588 void StatelessDatabaseOperations::ApplyInternal(IReadOnlyOperations* readOperations,
589 IReadWriteOperations* writeOperations) 589 IReadWriteOperations* writeOperations)
590 { 590 {
591 boost::shared_lock<boost::shared_mutex> lock(mutex_); // To protect "factory_" and "maxRetries_"
592
591 if ((readOperations == NULL && writeOperations == NULL) || 593 if ((readOperations == NULL && writeOperations == NULL) ||
592 (readOperations != NULL && writeOperations != NULL)) 594 (readOperations != NULL && writeOperations != NULL))
593 { 595 {
594 throw OrthancException(ErrorCode_InternalError); 596 throw OrthancException(ErrorCode_InternalError);
595 } 597 }
597 if (factory_.get() == NULL) 599 if (factory_.get() == NULL)
598 { 600 {
599 throw OrthancException(ErrorCode_BadSequenceOfCalls, "No transaction context was provided"); 601 throw OrthancException(ErrorCode_BadSequenceOfCalls, "No transaction context was provided");
600 } 602 }
601 603
602 unsigned int count = 0; 604 unsigned int attempt = 0;
603 605
604 for (;;) 606 for (;;)
605 { 607 {
606 try 608 try
607 { 609 {
636 } 638 }
637 catch (OrthancException& e) 639 catch (OrthancException& e)
638 { 640 {
639 if (e.GetErrorCode() == ErrorCode_DatabaseCannotSerialize) 641 if (e.GetErrorCode() == ErrorCode_DatabaseCannotSerialize)
640 { 642 {
641 if (count >= maxRetries_) 643 if (attempt >= maxRetries_)
642 { 644 {
643 throw; 645 throw;
644 } 646 }
645 else 647 else
646 { 648 {
647 count++; 649 attempt++;
648 boost::this_thread::sleep(boost::posix_time::milliseconds(100 * count)); 650
651 // The "rand()" adds some jitter to de-synchronize writers
652 boost::this_thread::sleep(boost::posix_time::milliseconds(50 * attempt + 5 * (rand() % 10)));
649 } 653 }
650 } 654 }
651 else 655 else
652 { 656 {
653 throw; 657 throw;
657 } 661 }
658 662
659 663
660 StatelessDatabaseOperations::StatelessDatabaseOperations(IDatabaseWrapper& db) : 664 StatelessDatabaseOperations::StatelessDatabaseOperations(IDatabaseWrapper& db) :
661 db_(db), 665 db_(db),
662 maxRetries_(10),
663 mainDicomTagsRegistry_(new MainDicomTagsRegistry), 666 mainDicomTagsRegistry_(new MainDicomTagsRegistry),
664 hasFlushToDisk_(db.HasFlushToDisk()) 667 hasFlushToDisk_(db.HasFlushToDisk()),
668 maxRetries_(0)
665 { 669 {
666 } 670 }
667 671
668 672
669 void StatelessDatabaseOperations::FlushToDisk() 673 void StatelessDatabaseOperations::FlushToDisk()
679 } 683 }
680 684
681 685
682 void StatelessDatabaseOperations::SetTransactionContextFactory(ITransactionContextFactory* factory) 686 void StatelessDatabaseOperations::SetTransactionContextFactory(ITransactionContextFactory* factory)
683 { 687 {
688 boost::unique_lock<boost::shared_mutex> lock(mutex_);
689
684 if (factory == NULL) 690 if (factory == NULL)
685 { 691 {
686 throw OrthancException(ErrorCode_NullPointer); 692 throw OrthancException(ErrorCode_NullPointer);
687 } 693 }
688 else if (factory_.get() != NULL) 694 else if (factory_.get() != NULL)
693 { 699 {
694 factory_.reset(factory); 700 factory_.reset(factory);
695 } 701 }
696 } 702 }
697 703
704
705 void StatelessDatabaseOperations::SetMaxDatabaseRetries(unsigned int maxRetries)
706 {
707 boost::unique_lock<boost::shared_mutex> lock(mutex_);
708 maxRetries_ = maxRetries;
709 }
710
698 711
699 void StatelessDatabaseOperations::Apply(IReadOnlyOperations& operations) 712 void StatelessDatabaseOperations::Apply(IReadOnlyOperations& operations)
700 { 713 {
701 ApplyInternal(&operations, NULL); 714 ApplyInternal(&operations, NULL);
702 } 715 }