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::list< PublicKeyData > _data
std::string asString() const
Returns a default string representation of the Url object.
PickResult pickBestMirror(const std::vector< Url > &mirrors)
sigc::connection _queueEmptyConn
Timer::Ptr _newMirrSigDelay
std::shared_ptr< Mirror > MirrorHandle
void registerMirrors(const std::vector< zypp::media::MetalinkMirror > &urls)
std::string makeKey(const zypp::Url &url) const
std::shared_ptr< MirrorControl > Ptr
SignalProxy< void()> sigAllMirrorsReady()
SignalProxy< void()> sigNewMirrorsReady()
Signal< void()> _sigNewMirrorsReady
NetworkRequestDispatcher::Ptr _dispatcher
std::unordered_map< std::string, MirrorHandle > _handles
Signal< void()> _sigAllMirrorsReady
The NetworkRequestError class Represents a error that occured in.
std::string toString() const
toString Returns a string representation of the error
bool hasError() const
Checks if there was a error with the request.
SignalProxy< void(NetworkRequest &req, const NetworkRequestError &err)> sigFinished()
Signals that the download finished.
std::optional< Timings > timings() const
After the request is finished query the timings that were collected during download.
std::string extendedErrorString() const
In some cases, curl can provide extended error information collected at runtime.
NetworkRequestError error() const
Returns the last set Error.
constexpr uint defaultMaxConnections
constexpr uint defaultSampleTime
constexpr uint penaltyIncrease
static const ViewOption WITH_SCHEME
Option to include scheme name in the URL string.
static const ViewOption WITH_PORT
Option to include port number in the URL string.
static const ViewOption EMPTY_AUTHORITY
Explicitely include the URL authority separator "//".
static const ViewOption WITH_HOST
Option to include hostname in the URL string.
void finishTransfer(const bool success)
uint maxConnections() const
bool hasFreeConnections() const
Mirror(MirrorControl &parent)