11#include <zypp-core/zyppng/base/EventDispatcher>
12#include <zypp-core/zyppng/base/Signals>
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 )
250 return url.asString( zypp::Url::ViewOptions::WITH_SCHEME +
251 zypp::Url::ViewOptions::WITH_HOST +
252 zypp::Url::ViewOptions::WITH_PORT +
253 zypp::Url::ViewOptions::EMPTY_AUTHORITY
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
287 return _data->_myHandle.operator bool();
292 return _data->_myHandle;
295 MirrorRef::Helper::~Helper()
297 if ( _cancelOnDestruct )
298 _myHandle->cancelTransfer();
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
~MirrorControl() override
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.
static std::shared_ptr< Timer > create()
Creates a new Timer object, the timer is not started at this point.
SignalProxy< void(Timer &t)> sigExpired()
This signal is always emitted when the timer expires.
constexpr uint defaultMaxConnections
constexpr uint defaultSampleTime
constexpr uint penaltyIncrease
friend class MirrorControl
void finishTransfer(const bool success)
uint maxConnections() const
bool hasFreeConnections() const
Mirror(MirrorControl &parent)