5 #include <zypp-core/zyppng/io/IODevice> 6 #include <zypp-core/Url.h> 7 #include <zypp-core/base/DtorReset> 8 #include <zypp-core/fs/PathInfo.h> 9 #include <zypp-media/MediaException> 10 #include <zypp-media/FileCheckException> 11 #include <zypp-media/CDTools> 23 , _workDir(
std::move(workDir) )
32 MIL <<
"Provider workdir is: " <<
_workDir << std::endl;
41 std::string_view reasonStr;
44 reasonStr =
"ProvideStart";
47 reasonStr =
"QueueIdle";
50 reasonStr =
"EnqueueItem";
53 reasonStr =
"EnqueueReq";
56 reasonStr =
"FinishReq";
59 reasonStr =
"RestartAttach";
62 DBG <<
"Triggering the schedule timer (" << reasonStr <<
")" << std::endl;
76 DBG_PRV <<
"Scheduling triggered during scheduling, returning immediately." << std::endl;
81 #ifdef _SC_NPROCESSORS_ONLN 82 sysconf(_SC_NPROCESSORS_ONLN) * 2;
88 constexpr
auto findLaziestWorker = [](
const auto &workerQueues,
const auto &idleNames ) {
89 auto candidate = workerQueues.end();
93 for (
const auto &name : idleNames ) {
94 auto thisElem = workerQueues.find(name);
95 if ( thisElem == workerQueues.end() )
98 const auto idleS = thisElem->second->idleSince();
100 && ( candidate == workerQueues.end() || *idleS < candidateIdleSince ) ) {
101 candidateIdleSince = *idleS;
102 candidate = thisElem;
106 if ( candidate != workerQueues.end() )
107 MIL_PRV <<
"Found idle worker:" << candidate->first <<
" idle since: " << candidateIdleSince.time_since_epoch().count() << std::endl;
115 if ( iMedia->_refCount > 0 ) {
116 MIL_PRV <<
"Not releasing media " << iMedia->_name <<
" refcount is not zero" << std::endl;
120 if ( iMedia->_workerType == ProvideQueue::Config::Downloading ) {
122 if ( std::chrono::steady_clock::now() - iMedia->_idleSince >= std::chrono::hours(1) ) {
123 MIL <<
"Detaching medium " << iMedia->_name <<
" for baseUrl " << iMedia->_attachedUrl << std::endl;
127 MIL_PRV <<
"Not releasing media " << iMedia->_name <<
" downloading worker and not timed out yet." << std::endl;
131 auto bQueue = iMedia->_backingQueue.lock();
138 MIL <<
"Detaching medium " << iMedia->_name <<
" for baseUrl " << iMedia->_attachedUrl << std::endl;
139 bQueue->enqueue ( *req );
143 ERR <<
"Could not send detach request, creating the request failed" << std::endl;
146 ERR <<
"Could not send detach request since no backing queue was defined" << std::endl;
155 const auto schedStart = std::chrono::steady_clock::now();
156 MIL_PRV <<
"Start scheduling" << std::endl;
159 const auto dur = std::chrono::steady_clock::now() - schedStart;
160 MIL_PRV <<
"Exit scheduling after:" << std::chrono::duration_cast<std::chrono::milliseconds>( dur ).count () << std::endl;
164 for (
auto it =
_items.begin (); it !=
_items.end(); ) {
180 for(
auto queueIter =
_queues.begin(); queueIter !=
_queues.end(); queueIter ++ ) {
182 const auto &scheme = queueIter->_schemeName;
183 auto &queue = queueIter->_requests;
190 MIL_PRV <<
"Start scheduling for scheme:" << scheme <<
" queue size is: " << queue.size() << std::endl;
194 ERR <<
"Scheme: " << scheme <<
" failed to return a valid configuration." << std::endl;
196 while( queue.size() ) {
197 auto item = std::move( queue.front() );
207 const auto &config = configOpt.get();
208 const auto isSingleInstance = ( (config.cfg_flags() & ProvideQueue::Config::SingleInstance) == ProvideQueue::Config::SingleInstance );
209 if ( config.worker_type() == ProvideQueue::Config::Downloading && !isSingleInstance ) {
211 for(
auto i = queue.begin (); i != queue.end(); ) {
215 while ( i != queue.end() && !(*i) ) {
219 if ( i == queue.end() )
222 ProvideRequestRef item = *i;
226 if( item->code() == ProvideMessage::Code::Attach || item->code() == ProvideMessage::Code::Detach ) {
229 item->owner()->finishReq(
nullptr, item,
ZYPP_EXCPT_PTR(
zypp::Exception(
"Downloading Queues do not support ProvideMessage::Code::Attach requests") ) );
233 MIL_PRV <<
"Trying to schedule request: " << item->urls().front() << std::endl;
236 int existingTypeWorkers = 0;
239 int existingConnections = 0;
242 std::vector< std::pair<zypp::Url, ProvideQueue*> > possibleHostWorkers;
245 std::vector<std::string> idleWorkers;
248 std::vector<zypp::Url> mirrsWithoutWorker;
249 for (
const auto &url : item->urls() ) {
252 MIL <<
"Mirror URL " << url <<
" is incompatible with current scheme: " << scheme <<
", ignoring." << std::endl;
256 if( item->owner()->canRedirectTo( item, url ) )
257 mirrsWithoutWorker.push_back( url );
259 MIL_PRV <<
"URL was rejected" << url << std::endl;
264 if( mirrsWithoutWorker.size() == 0 ) {
265 MIL <<
"Request has NO usable URLs" << std::endl;
274 if ( ProvideQueue::Config::Downloading != workerQueue->workerConfig().worker_type() )
277 existingTypeWorkers ++;
278 existingConnections += workerQueue->activeRequests();
280 if ( workerQueue->isIdle() )
286 for (
auto i = mirrsWithoutWorker.begin (); i != mirrsWithoutWorker.end(); ) {
288 if ( u.getHost() == workerQueue->hostname() ) {
290 possibleHostWorkers.push_back( {u, workerQueue.get()} );
291 i = mirrsWithoutWorker.erase( i );
300 MIL <<
"Current stats: " << std::endl;
301 MIL <<
"Existing type workers: " << existingTypeWorkers << std::endl;
302 MIL <<
"Existing active connections: " << existingConnections << std::endl;
303 MIL <<
"Possible host workers: "<< possibleHostWorkers.size() << std::endl;
304 MIL <<
"Mirrors without worker: " << mirrsWithoutWorker.size() << std::endl;
309 MIL_PRV <<
"Reached maximum nr of connections, break" << std::endl;
316 && mirrsWithoutWorker.size() ) {
318 MIL_PRV <<
"Free worker slots and available mirror URLs, starting a new worker" << std::endl;
322 for(
const auto &url : mirrsWithoutWorker ) {
325 if ( !item->owner()->safeRedirectTo ( item, url ) )
328 ProvideQueueRef q = std::make_shared<ProvideQueue>( *this );
329 if ( !q->startup( scheme,
_workDir / scheme / url.getHost(), url.getHost() ) ) {
333 MIL_PRV <<
"Started worker for " << url.getHost() <<
" enqueing request" << std::endl;
335 item->setActiveUrl(url);
352 if ( possibleHostWorkers.size() ) {
354 MIL_PRV <<
"No free worker slots, looking for the best existing worker" << std::endl;
356 while( possibleHostWorkers.size () ) {
357 std::vector< std::pair<zypp::Url, ProvideQueue *> >::iterator candidate = possibleHostWorkers.begin();
358 for (
auto i = candidate+1; i != possibleHostWorkers.end(); i++ ) {
359 if ( i->second->activeRequests () < candidate->second->activeRequests () )
363 if ( !item->owner()->safeRedirectTo( item, candidate->first ) ) {
364 possibleHostWorkers.erase( candidate );
368 MIL_PRV <<
"Using existing worker " << candidate->first.getHost() <<
" to download request" << std::endl;
371 item->setActiveUrl( candidate->first );
372 candidate->second->enqueue( item );
384 if ( idleWorkers.size() && mirrsWithoutWorker.size() ) {
386 MIL_PRV <<
"No free worker slots, no slots in existing queues, trying to decomission idle queues." << std::endl;
388 auto candidate = findLaziestWorker(
_workerQueues, idleWorkers );
397 for(
const auto &url : mirrsWithoutWorker ) {
399 if ( !item->owner()->safeRedirectTo ( item, url ) )
402 ProvideQueueRef q = std::make_shared<ProvideQueue>( *this );
403 if ( !q->startup( scheme,
_workDir / scheme / url.getHost(), url.getHost() ) ) {
407 MIL_PRV <<
"Replaced worker for " << url.getHost() <<
", enqueing request" << std::endl;
409 item->setActiveUrl(url);
426 MIL_PRV <<
"End of line, deferring request for next try." << std::endl;
430 }
else if ( config.worker_type() == ProvideQueue::Config::CPUBound && !isSingleInstance ) {
432 for(
auto i = queue.begin (); i != queue.end(); ) {
436 while ( i != queue.end() && !(*i) ) {
440 if ( i == queue.end() )
444 ProvideRequestRef item = *i;
448 if( item->code() == ProvideMessage::Code::Attach || item->code() == ProvideMessage::Code::Detach ) {
450 if ( item->owner () )
451 item->owner()->finishReq(
nullptr, item,
ZYPP_EXCPT_PTR(
zypp::Exception(
"CPU bound Queues do not support ProvideAttachSpecRef requests") ) );
455 MIL_PRV <<
"Trying to schedule request: " << item->urls().front() << std::endl;
458 int existingTypeWorkers = 0;
459 int existingSchemeWorkers = 0;
462 std::vector< ProvideQueue* > possibleWorkers;
465 std::vector<std::string> idleWorkers;
471 for (
const auto &tmpurl : item->urls() ) {
473 MIL <<
"Mirror URL " << tmpurl <<
" is incompatible with current scheme: " << scheme <<
", ignoring." << std::endl;
482 MIL <<
"Request has NO usable URLs" << std::endl;
491 if ( ProvideQueue::Config::CPUBound != workerQueue->workerConfig().worker_type() )
496 existingTypeWorkers ++;
498 existingSchemeWorkers++;
499 if ( workerQueue->canScheduleMore() )
500 possibleWorkers.push_back(workerQueue.get());
503 if ( workerQueue->isIdle() )
508 MIL <<
"Current stats: " << std::endl;
509 MIL <<
"Existing type workers: " << existingTypeWorkers << std::endl;
510 MIL <<
"Possible CPU workers: "<< possibleWorkers.size() << std::endl;
514 if ( possibleWorkers.size() ) {
516 for (
auto &w : possibleWorkers ) {
518 MIL_PRV <<
"Using existing idle worker to provide request" << std::endl;
520 item->owner()->redirectTo ( item, url );
521 item->setActiveUrl( url );
533 if ( existingTypeWorkers < cpuLimit ) {
535 MIL_PRV <<
"Free CPU slots, starting a new worker" << std::endl;
538 item->owner()->redirectTo ( item, url );
540 ProvideQueueRef q = std::make_shared<ProvideQueue>( *this );
541 if ( q->startup( scheme,
_workDir / scheme ) ) {
543 item->setActiveUrl(url);
560 if ( possibleWorkers.size() ) {
561 MIL_PRV <<
"No free CPU slots, looking for the best existing worker" << std::endl;
563 if( possibleWorkers.size () ) {
564 std::vector<ProvideQueue *>::iterator candidate = possibleWorkers.begin();
565 for (
auto i = candidate+1; i != possibleWorkers.end(); i++ ) {
566 if ( (*i)->activeRequests () < (*candidate)->activeRequests () )
571 item->owner()->redirectTo ( item, url );
573 MIL_PRV <<
"Using existing worker to provide request" << std::endl;
574 item->setActiveUrl( url );
575 (*candidate)->enqueue( item );
583 if ( idleWorkers.size() ) {
585 MIL_PRV <<
"No free CPU slots, no slots in existing queues, trying to decomission idle queues." << std::endl;
587 auto candidate = findLaziestWorker(
_workerQueues, idleWorkers );
593 item->owner()->redirectTo ( item, url );
595 ProvideQueueRef q = std::make_shared<ProvideQueue>( *this );
596 if ( q->startup( scheme,
_workDir / scheme ) ) {
598 MIL_PRV <<
"Replaced worker, enqueing request" << std::endl;
600 item->setActiveUrl(url);
616 MIL_PRV <<
"No idle workers and no free CPU spots, wait for the next schedule run" << std::endl;
621 MIL_PRV <<
"End of line, deferring request for next try." << std::endl;
628 for(
auto i = queue.begin (); i != queue.end(); ) {
632 while ( i != queue.end() && !(*i) ) {
636 if ( i == queue.end() )
640 ProvideRequestRef item = *i;
641 MIL_PRV <<
"Trying to schedule request: " << item->urls().front() << std::endl;
646 for (
const auto &tmpurl : item->urls() ) {
648 MIL <<
"Mirror URL " << tmpurl <<
" is incompatible with current scheme: " << scheme <<
", ignoring." << std::endl;
657 MIL <<
"Request has NO usable URLs" << std::endl;
667 ProvideQueueRef q = std::make_shared<ProvideQueue>( *this );
668 if ( !q->startup( scheme,
_workDir / scheme ) ) {
669 ERR <<
"Worker startup failed!" << std::endl;
678 MIL_PRV <<
"Started worker, enqueing request" << std::endl;
682 MIL_PRV <<
"Found worker, enqueing request" << std::endl;
687 item->owner()->redirectTo ( item, url );
689 item->setActiveUrl(url);
715 return expected<ProvideQueue::Config>::success(i->second);
723 return expected<ProvideQueue::Config>::success(newItem.first->second);
729 const auto &key = downloadedFile.
asString();
739 i.first->second._deathTimer.reset();
740 return i.first->second._file;
744 return i.first->second._file;
749 const auto &key = downloadedFile.
asString();
761 auto elem = std::find_if(
_items.begin(),
_items.end(), [item](
const auto &i){
return i.get() == item; } );
762 if ( elem !=
_items.end() ) {
780 MIL_PRV <<
"Generated new ID for media attachment: " <<
str << std::endl;
787 MIL_PRV <<
"New media attachment with id: " <<
id << std::endl;
795 auto existingQ = std::find_if(
_queues.begin (),
_queues.end(), [&schemeName](
const auto &qItem) {
796 return (qItem._schemeName == schemeName);
798 if ( existingQ !=
_queues.end() ) {
799 existingQ->_requests.push_back(req);
810 auto queue = req->currentQueue ();
812 queue->cancel( req.get(), error );
817 auto elem = std::find( q._requests.begin(), q._requests.end(), req );
818 if ( elem != q._requests.end() ) {
819 q._requests.erase(elem);
822 req->owner()->finishReq(
nullptr, req, error );
838 if ( v.second.get() == &q )
860 DBG_PRV <<
"Pulse timeout" << std::endl;
862 auto now = std::chrono::steady_clock::now();
868 auto &cacheItem = i->second;
869 if ( cacheItem._file.unique() ) {
870 if ( cacheItem._deathTimer ) {
871 if ( now - *cacheItem._deathTimer < std::chrono::seconds(20) ) {
872 MIL <<
"Releasing file " << *i->second._file <<
" from cache, death timeout." << std::endl;
878 cacheItem._deathTimer = std::chrono::steady_clock::now();
903 auto i = std::find(
_items.begin(),
_items.end(), itemRef );
904 if ( i ==
_items.end() ) {
905 ERR <<
"State of unknown Item changed, ignoring" << std::endl;
943 return _ref->_parent.lock();
953 return _ref->_hdlName;
965 return ProvideRef(
new Provide(workDir) );
970 return attachMedia ( std::vector<zypp::Url>{url}, request );
977 if ( urls.empty() ) {
982 std::vector<zypp::Url> usableMirrs;
983 std::optional<ProvideQueue::Config> scheme;
985 for (
auto mirrIt = urls.begin() ; mirrIt != urls.end(); mirrIt++ ) {
986 const auto &s = d->schemeConfig( d->effectiveScheme( mirrIt->getScheme() ) );
988 WAR <<
"URL: " << *mirrIt <<
" is not supported, ignoring!" << std::endl;
993 usableMirrs.push_back ( *mirrIt );
995 if ( scheme->worker_type () == s->worker_type () ) {
996 usableMirrs.push_back( *mirrIt );
998 WAR <<
"URL: " << *mirrIt <<
" has different worker type than the primary URL: "<< usableMirrs.front() <<
", ignoring!" << std::endl;
1003 if ( !scheme || usableMirrs.empty() ) {
1008 auto &attachedMedia = d->attachedMediaInfos ();
1009 for (
auto &medium : attachedMedia ) {
1010 if ( medium.isSameMedium ( usableMirrs, request ) ) {
1012 return makeReadyResult( expected<Provide::MediaHandle>::success(
Provide::MediaHandle( *
this, medium._name) ) );
1018 return op->promise();
1025 if ( mediaRef.empty() )
1028 const auto i = std::find_if( d->_attachedMediaInfos.begin(), d->_attachedMediaInfos.end(), [&](
const auto &info ){
return info._name == mediaRef;} );
1029 if ( i == d->_attachedMediaInfos.end() ) {
1030 ERR <<
"Unknown media attach handle" << std::endl;
1043 return op->promise();
1048 return provide( std::vector<zypp::Url>{ url }, request );
1054 const auto i = std::find_if( d->_attachedMediaInfos.begin(), d->_attachedMediaInfos.end(), [&](
const auto &info ){
return info._name == attachHandle.
handle();} );
1055 if ( i == d->_attachedMediaInfos.end() ) {
1064 if ( i->_workerType == ProvideQueue::Config::SimpleMount || i->_workerType == ProvideQueue::Config::VolatileMount ) {
1079 return op->promise();
1090 if ( chksumRes.headers().contains(algorithm) )
1091 return expected<std::string>::success( chksumRes.headers().value(algorithm).asString() );
1105 return expected<zypp::ManagedFile>::success( copyRes.asManagedFile() );
1113 d->_isRunning =
true;
1114 d->_pulseTimer->start( 5000 );
1116 if ( d->_log ) d->_log->provideStart();
1121 d_func()->_workerPath = path;
1126 if ( !queueRef.empty() ) {
1134 d_func()->_log = tracker;
1139 return d_func()->_workDir;
1145 return d->_credManagerOptions;
1150 d_func()->_credManagerOptions = opt;
1155 return d_func()->_sigIdle;
1158 SignalProxy<Provide::MediaChangeAction ( const std::string &queueRef, const std::string &, const int32_t, const std::vector<std::string> &,
const std::optional<std::string> &)>
Provide::sigMediaChangeRequested()
1160 return d_func()->_sigMediaChange;
1163 SignalProxy< std::optional<zypp::media::AuthData> (
const zypp::Url &reqUrl,
const std::string &triedUsername,
const std::map<std::string, std::string> &extraValues ) >
Provide::sigAuthRequired()
1165 return d_func()->_sigAuthRequired;
1171 : _provider( parent )
1185 if ( sTime > sTime.min() && fTime >= sTime ) {
1186 auto duration = std::chrono::duration_cast<std::chrono::seconds>( item.
finishedTime() - item.
startTime() );
1187 if ( duration.count() )
1196 MIL <<
"Item failed" << std::endl;
1215 for (
const auto &i : prov->d_func()->items() ) {
1229 const auto &
stats = i->currentStats();
1230 const auto & prevStats = i->previousStats();
1231 if ( !
stats || !prevStats ) {
1232 ERR <<
"Bug! Stats should be initialized by now" << std::endl;
1240 tmpPartialBytes +=
stats->_bytesProvided;
1247 const auto now = std::chrono::steady_clock::now();
1248 const auto sinceLast = std::chrono::duration_cast<std::chrono::seconds>( now -
_stats.
_lastPulseTime );
1249 const auto lastFinB = lastPartialBytes + lastFinishedBytes;
1252 const auto diff = currFinB - lastFinB;
1256 if ( sinceLast >= std::chrono::seconds(1) )
1260 if ( sinceStart.count() ) {
std::string getScheme() const
Returns the scheme name of the URL.
constexpr auto DEFAULT_MAX_DYNAMIC_WORKERS
SignalProxy< void()> sigIdle()
const zypp::Pathname & providerWorkdir() const
zypp::ByteCount _finishedBytes
static ProvideFileItemRef create(const std::vector< zypp::Url > &urls, const ProvideFileSpec &request, ProvidePrivate &parent)
std::optional< zypp::ManagedFile > addToFileCache(const zypp::Pathname &downloadedFile)
bool queueRequest(ProvideRequestRef req)
ZYPP_IMPL_PRIVATE(Provide)
Pathname realpath() const
Returns this path as the absolute canonical pathname.
std::vector< AttachedMediaInfo > _attachedMediaInfos
AsyncOpRef< expected< ProvideRes > > provide(const std::vector< zypp::Url > &urls, const ProvideFileSpec &request)
const zypp::media::CredManagerOptions & credManangerOptions() const
ProvideStatus(ProvideRef parent)
std::list< ProvideItemRef > _items
void appendPathName(const Pathname &path_r, EEncoding eflag_r=zypp::url::E_DECODED)
Extend the path name.
Store and operate with byte count.
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
const zypp::Pathname & workerPath() const
virtual void itemFailed(ProvideItem &item)
std::string nextMediaId() const
std::string stripSuffix(const C_Str &str_r, const C_Str &suffix_r)
Strip a suffix_r from str_r and return the resulting string.
String related utilities and Regular expression matching.
void enqueue(ProvideRequestRef request)
AsyncOpRef< expected< std::string > > checksumForFile(const zypp::Pathname &p, const std::string &algorithm)
bool provideDebugEnabled()
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
std::unordered_map< std::string, ProvideQueue::Config > _schemeConfigs
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
zypp::Pathname _workerPath
std::chrono::time_point< std::chrono::steady_clock > TimePoint
static ProvideRef create(const zypp::Pathname &workDir="")
Timer::Ptr _scheduleTrigger
#define L_ENV_CONSTR_DEFINE_FUNC(ENV)
zypp::ByteCount _perSecond
std::chrono::steady_clock::time_point _lastPulseTime
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
void setAuthority(const std::string &authority)
Set the authority component in the URL.
void setCredManagerOptions(const zypp::media::CredManagerOptions &opt)
Assign a vaiable a certain value when going out of scope.
bool isInCache(const zypp::Pathname &downloadedFile) const
bool empty() const
Test for an empty path.
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
expected< ProvideQueue::Config > schemeConfig(const std::string &scheme)
ProvidePrivate(zypp::Pathname &&workDir, Provide &pub)
std::vector< AttachedMediaInfo > & attachedMediaInfos()
std::deque< QueueItem > _queues
void onItemStateChanged(ProvideItem &item)
std::list< ProvideItemRef > & items()
SignalProxy< MediaChangeAction(const std::string &queueRef, const std::string &label, const int32_t mediaNr, const std::vector< std::string > &devices, const std::optional< std::string > &desc)> sigMediaChangeRequested()
void setScheme(const std::string &scheme)
Set the scheme name in the URL.
int unlink(const Pathname &path)
Like 'unlink'.
const std::string & asString() const
String representation.
const Config & workerConfig() const
zypp::ByteCount _expectedBytes
virtual void itemDone(ProvideItem &item)
bool ejectDevice(const std::string &queueRef, const std::string &device)
void setWorkerPath(const zypp::Pathname &path)
void onPulseTimeout(Timer &)
const std::optional< ItemStats > & currentStats() const
bool startsWith(const C_Str &str_r, const C_Str &prefix_r)
alias for hasPrefix
ProvideMediaHandle MediaHandle
void schedule(ScheduleReason reason)
virtual void provideStart()
constexpr auto DEFAULT_CPU_WORKERS
zypp::ByteCount _partialBytes
bool isValid() const
Verifies the Url.
constexpr auto DEFAULT_ACTIVE_CONN_PER_HOST
const std::string queueName(ProvideQueue &q) const
void dequeueItem(ProvideItem *item)
Provide(const zypp::Pathname &workDir)
zypp::media::CredManagerOptions _credManagerOptions
bool startup(const std::string &workerScheme, const zypp::Pathname &workDir, const std::string &hostname="")
constexpr std::string_view DEFAULT_PROVIDE_WORKER_PATH
std::unordered_map< std::string, FileCacheItem > _fileCache
bool dequeueRequest(ProvideRequestRef req, std::exception_ptr error)
AsyncOpRef< expected< MediaHandle > > attachMedia(const std::vector< zypp::Url > &urls, const ProvideMediaSpec &request)
Base class for Exception.
constexpr auto DEFAULT_ACTIVE_CONN
void queueItem(ProvideItemRef item)
reference value() const
Reference to the Tp object.
zypp::media::CredManagerOptions & credManagerOptions()
static expected< ProvideRequestRef > createDetach(const zypp::Url &url)
zypp::ByteCount _perSecondSinceLastPulse
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
void setStatusTracker(ProvideStatusRef tracker)
std::unordered_map< std::string, std::string > _workerAlias
std::chrono::steady_clock::time_point _startTime
const Stats & stats() const
AsyncOpRef< expected< zypp::ManagedFile > > copyFile(const zypp::Pathname &source, const zypp::Pathname &target)
Wrapper class for ::stat/::lstat.
constexpr std::string_view device("device")
AttachedMediaInfo & addMedium(zypp::proto::Capabilities::WorkerType workerType, const zypp::Url &baseUrl, ProvideMediaSpec &spec)
void releaseMedia(const std::string &mediaRef)
Easy-to use interface to the ZYPP dependency resolver.
std::unordered_map< std::string, ProvideQueueRef > _workerQueues
std::string effectiveScheme(const std::string &scheme) const
virtual std::chrono::steady_clock::time_point startTime() const
constexpr std::string_view ATTACHED_MEDIA_SUFFIX
virtual std::chrono::steady_clock::time_point finishedTime() const
SignalProxy< std::optional< zypp::media::AuthData > const zypp::Url &reqUrl, const std::string &triedUsername, const std::map< std::string, std::string > &extraValues) > sigAuthRequired()