From dd438e394193b5d850b4924aab05fa99f72d8a72 Mon Sep 17 00:00:00 2001 From: Steven Murray <Steven.Murray@cern.ch> Date: Mon, 29 Jan 2018 17:27:22 +0100 Subject: [PATCH] cta/CTA#186 CTA should cope with idle database connections being dropped by the database server RdbmsCatalogue::tapeMountedForRetrieve() should re-connect to database if connection lost. --- catalogue/RdbmsCatalogue.cpp | 28 ++++++++++++++++++++++++++++ catalogue/RdbmsCatalogue.hpp | 15 +++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp index ce083caed4..b0ede92245 100644 --- a/catalogue/RdbmsCatalogue.cpp +++ b/catalogue/RdbmsCatalogue.cpp @@ -2248,6 +2248,32 @@ void RdbmsCatalogue::tapeMountedForArchiveInternal(const std::string &vid, const // tapeMountedForRetrieve //------------------------------------------------------------------------------ void RdbmsCatalogue::tapeMountedForRetrieve(const std::string &vid, const std::string &drive) { + const uint32_t maxTries = 3; + + for(uint32_t tryNb = 1; tryNb <= maxTries; tryNb++) { + try { + return tapeMountedForRetrieveInternal(vid, drive); + } catch(exception::LostDatabaseConnection &lc) { + // Ignore lost connection + std::list<log::Param> params = { + {"maxTries", maxTries}, + {"tryNb", tryNb}, + {"msg", lc.getMessage()} + }; + m_log(cta::log::WARNING, "Lost database connection", params); + } + } + + exception::Exception ex; + ex.getMessage() << std::string(__FUNCTION__) << " failed: Lost the database connection after trying " << maxTries << + " times"; + throw ex; +} + +//------------------------------------------------------------------------------ +// tapeMountedForRetrieveInternal +//------------------------------------------------------------------------------ +void RdbmsCatalogue::tapeMountedForRetrieveInternal(const std::string &vid, const std::string &drive) { try { const time_t now = time(nullptr); const char *const sql = @@ -2266,6 +2292,8 @@ void RdbmsCatalogue::tapeMountedForRetrieve(const std::string &vid, const std::s if(0 == stmt.getNbAffectedRows()) { throw exception::UserError(std::string("Cannot modify tape ") + vid + " because it does not exist"); } + } catch(exception::LostDatabaseConnection &) { + throw; } catch(exception::UserError &) { throw; } catch (exception::Exception &ex) { diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp index c020a25683..391cdea5e7 100644 --- a/catalogue/RdbmsCatalogue.hpp +++ b/catalogue/RdbmsCatalogue.hpp @@ -1020,6 +1020,21 @@ protected: */ void tapeMountedForArchiveInternal(const std::string &vid, const std::string &drive); + /** + * Notifies the CTA catalogue that the specified tape has been mounted in + * order to retrieve files. + * + * The purpose of this method is to keep track of which drive mounted a given + * tape for retrieving files last. + * + * This internal method can be re-tried if it throws a LostDatabaseConnection + * exception. + * + * @param vid The volume identifier of the tape. + * @param drive The name of the drive where the tape was mounted. + */ + void tapeMountedForRetrieveInternal(const std::string &vid, const std::string &drive); + /** * Prepares the catalogue for a new archive file and returns the information * required to queue the associated archive request. -- GitLab