11 #include <zypp-core/zyppng/base/EventDispatcher> 12 #include <zypp-core/zyppng/base/Signals> 13 #include <zypp-core/base/String.h> 34 successfulTransfers++;
55 return ( runningTransfers < maxConnections() );
60 const auto newCount = runningTransfers - 1;
64 bool stillLoaded = ( newCount ) >= maxConnections();
67 _parent._sigNewMirrorsReady.emit();
80 _dispatcher = std::make_shared<NetworkRequestDispatcher>();
81 _queueEmptyConn =
_dispatcher->connectFunc( &NetworkRequestDispatcher::sigQueueFinished, [
this ]( NetworkRequestDispatcher& ) {
84 std::vector< std::unordered_map<std::string, MirrorHandle>::const_iterator > allOfEm;
86 allOfEm.push_back( i );
89 std::sort( allOfEm.begin(), allOfEm.end(), [](
const auto &
a,
const auto &
b ){
90 return (
zypp::str::compareCI(
a->second->mirrorUrl.asString().c_str(),
b->second->mirrorUrl.asString().c_str() ) < 0 );
93 DBG_MEDIA <<
"Finished probing mirrors, these are the results: \n";
94 for (
const auto &iter : allOfEm ) {
95 DBG_MEDIA <<
"Mirror: " << iter->second->mirrorUrl <<
", rating is: " << iter->second->rating <<
"\n";
97 DBG_MEDIA <<
"End Mirror probing results." << std::endl;
115 MIL <<
"Destroying MirrorControl while measurements are still running, aborting" << std::endl;
117 if ( mirr.second->_request ) {
118 mirr.second->_finishedConn.disconnect();
128 bool doesKnowSomeMirrors =
false;
129 for (
const auto &mirror : urls ) {
131 const auto scheme = mirror.url.getScheme();
132 if ( scheme ==
"http" || scheme ==
"https" || scheme ==
"ftp" || scheme ==
"tftp" ) {
134 const std::string urlKey =
makeKey( mirror.url );
137 const auto hndlIt =
_handles.find( urlKey );
139 doesKnowSomeMirrors =
true;
143 auto mirrorHandle = std::shared_ptr<Mirror>(
new Mirror(*
this) );
144 mirrorHandle->rating = mirror.priority;
145 mirrorHandle->_maxConnections = mirror.maxConnections;
146 mirrorHandle->mirrorUrl = mirror.url;
147 mirrorHandle->mirrorUrl.setPathName(
"/");
152 mirrorHandle->_request->transferSettings().setConnectTimeout(
defaultSampleTime );
158 const auto timings = req.
timings();
159 std::chrono::milliseconds connTime;
161 connTime = std::chrono::duration_cast<std::chrono::milliseconds>(timings->connect - timings->namelookup);
167 DBG_MEDIA <<
"Got rating for mirror: " << mirrorHandle->mirrorUrl <<
", rating was " << mirrorHandle->rating;
168 mirrorHandle->rating += connTime.count();
169 DBG_MEDIA <<
" rating is now " << mirrorHandle->rating <<
" conn time was " << connTime.count() << std::endl;
172 mirrorHandle->_finishedConn.disconnect();
173 mirrorHandle->_request.reset();
176 someReadyDelay->start( 0 );
180 _handles.insert( std::make_pair(urlKey, mirrorHandle ) );
184 if ( doesKnowSomeMirrors )
195 bool hasPendingRating =
false;
196 std::vector< MirrorPick > possibleMirrs;
197 for (
auto i = mirrors.begin(); i != mirrors.end(); i++ ) {
198 const auto key =
makeKey( *i );
199 const auto hdlIt = this->
_handles.find( key );
203 if ( hdlIt->second->_request ) {
204 hasPendingRating =
true;
207 possibleMirrs.push_back( std::make_pair( i, hdlIt->second ) );
210 if ( possibleMirrs.empty() && hasPendingRating ) {
215 std::stable_sort( possibleMirrs.begin(), possibleMirrs.end(), [](
const auto &
a,
const auto &
b ) {
216 return a.second->rating <
b.second->rating;
219 bool hasLoadedOne =
false;
220 for (
const auto &mirr : possibleMirrs ) {
221 if ( !mirr.second->hasFreeConnections() ) {
225 if ( mirr.second->failedTransfers >= 10 )
261 _data = std::make_shared<Helper>( handle, false );
264 MirrorRef::~MirrorRef()
267 void MirrorRef::startTransfer()
269 _data->_myHandle->startTransfer();
270 _data->_cancelOnDestruct =
true;
273 void MirrorRef::finishTransfer(
const bool success)
275 _data->_cancelOnDestruct =
false;
276 _data->_myHandle->finishTransfer( success );
279 void MirrorRef::cancelTransfer()
281 _data->_cancelOnDestruct =
false;
282 _data->_myHandle->cancelTransfer();
285 MirrorRef::operator
bool()
const 292 return _data->_myHandle;
295 MirrorRef::Helper::~Helper()
297 if ( _cancelOnDestruct )
298 _myHandle->cancelTransfer();
std::optional< Timings > timings() const
After the request is finished query the timings that were collected during download.
SignalProxy< void()> sigNewMirrorsReady()
constexpr uint defaultSampleTime
bool hasFreeConnections() const
static const ViewOption WITH_SCHEME
Option to include scheme name in the URL string.
static const ViewOption WITH_HOST
Option to include hostname in the URL string.
std::string toString() const
toString Returns a string representation of the error
Signal< void()> _sigNewMirrorsReady
bool hasError() const
Checks if there was a error with the request.
void registerMirrors(const std::vector< zypp::media::MetalinkMirror > &urls)
sigc::connection _queueEmptyConn
std::string asString() const
Returns a default string representation of the Url object.
std::list< PublicKeyData > _data
static const ViewOption EMPTY_AUTHORITY
Explicitely include the URL authority separator "//".
The NetworkRequestError class Represents a error that occured in.
NetworkRequestError error() const
Returns the last set Error.
uint maxConnections() const
std::string extendedErrorString() const
In some cases, curl can provide extended error information collected at runtime.
void finishTransfer(const bool success)
Mirror(MirrorControl &parent)
constexpr uint defaultMaxConnections
int compareCI(const C_Str &lhs, const C_Str &rhs)
Signal< void()> _sigAllMirrorsReady
constexpr uint penaltyIncrease
std::shared_ptr< Mirror > MirrorHandle
SignalProxy< void(NetworkRequest &req, const NetworkRequestError &err)> sigFinished()
Signals that the download finished.
SignalProxy< void()> sigAllMirrorsReady()
std::string makeKey(const zypp::Url &url) const
static const ViewOption WITH_PORT
Option to include port number in the URL string.
Timer::Ptr _newMirrSigDelay
std::unordered_map< std::string, MirrorHandle > _handles
PickResult pickBestMirror(const std::vector< Url > &mirrors)
std::shared_ptr< MirrorControl > Ptr
NetworkRequestDispatcher::Ptr _dispatcher