Skip to content

Commit 7c06f31

Browse files
authored
Merge pull request #47593 from makortel/xrdAdaptorRetryInactive
XrdAdaptor: Use inactive sources first before trying to open a new source when handling a failed request
2 parents c80b7ef + 688b9dc commit 7c06f31

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

Utilities/XrdAdaptor/src/XrdRequestManager.cc

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -856,17 +856,39 @@ void RequestManager::requestFailure(std::shared_ptr<XrdAdaptor::ClientRequest> c
856856
m_disabledSources.insert(source_ptr);
857857

858858
std::unique_lock<std::recursive_mutex> sentry(m_source_mutex);
859-
if ((!m_activeSources.empty()) && (m_activeSources[0].get() == source_ptr.get())) {
859+
// Remove the failed source from the container of active sources
860+
if (auto found = std::ranges::find_if(
861+
m_activeSources, [&source_ptr](const std::shared_ptr<Source> &src) { return src.get() == source_ptr.get(); });
862+
found != m_activeSources.end()) {
860863
auto oldSources = m_activeSources;
861-
m_activeSources.erase(m_activeSources.begin());
862-
reportSiteChange(oldSources, m_activeSources);
863-
} else if ((m_activeSources.size() > 1) && (m_activeSources[1].get() == source_ptr.get())) {
864-
auto oldSources = m_activeSources;
865-
m_activeSources.erase(m_activeSources.begin() + 1);
864+
m_activeSources.erase(found);
866865
reportSiteChange(oldSources, m_activeSources);
867866
}
867+
// Find a new source to send the request to
868+
// - First, if there is another active source, use it
869+
// - Then, if there are no active sources, if there are inactive
870+
// sources, use the best inactive source
871+
// - Then, if there are no active or inactice sources, try to open a
872+
// new connection for a new source
868873
std::shared_ptr<Source> new_source;
869-
if (m_activeSources.empty()) {
874+
if (not m_activeSources.empty()) {
875+
new_source = m_activeSources[0];
876+
} else if (not m_inactiveSources.empty()) {
877+
// similar logic as in checkSourcesImpl()
878+
// assume the "sort open delay" doesn't matter in case of a request failure
879+
auto bestInactiveSource =
880+
std::min_element(m_inactiveSources.begin(),
881+
m_inactiveSources.end(),
882+
[](const std::shared_ptr<Source> &s1, const std::shared_ptr<Source> &s2) {
883+
return s1->getQuality() < s2->getQuality();
884+
});
885+
new_source = *bestInactiveSource;
886+
887+
auto oldSources = m_activeSources;
888+
m_activeSources.push_back(*bestInactiveSource);
889+
m_inactiveSources.erase(bestInactiveSource);
890+
reportSiteChange(oldSources, m_activeSources);
891+
} else {
870892
std::shared_future<std::shared_ptr<Source>> future = m_open_handler->open();
871893
timespec now;
872894
GET_CLOCK_MONOTONIC(now);
@@ -910,8 +932,6 @@ void RequestManager::requestFailure(std::shared_ptr<XrdAdaptor::ClientRequest> c
910932
auto oldSources = m_activeSources;
911933
m_activeSources.push_back(new_source);
912934
reportSiteChange(oldSources, m_activeSources);
913-
} else {
914-
new_source = m_activeSources[0];
915935
}
916936
new_source->handle(c_ptr);
917937
}

0 commit comments

Comments
 (0)