[netinstall] Improve loader queue API a bit
- use load() to start loading - the FetchNextUnless class is useful in more spots in the loading process - set status explicitly on success (otherwise, a failure in a previous URL would leave a failure message lying around even when the module shows something useful)
This commit is contained in:
parent
03d086a233
commit
fdfe52efe2
@ -54,9 +54,11 @@ Config::status() const
|
||||
case Status::FailedBadData:
|
||||
return tr( "Network Installation. (Disabled: Received invalid groups data)" );
|
||||
case Status::FailedInternalError:
|
||||
return tr( "Network Installation. (Disabled: internal error)" );
|
||||
return tr( "Network Installation. (Disabled: Internal error)" );
|
||||
case Status::FailedNetworkError:
|
||||
return tr( "Network Installation. (Disabled: Unable to fetch package lists, check your network connection)" );
|
||||
case Status::FailedNoData:
|
||||
return tr( "Network Installation. (Disabled: No package list)" );
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}
|
||||
@ -89,6 +91,11 @@ Config::loadGroupList( const QVariantList& groupData )
|
||||
if ( m_model->rowCount() < 1 )
|
||||
{
|
||||
cWarning() << "NetInstall groups data was empty.";
|
||||
setStatus( Status::FailedNoData );
|
||||
}
|
||||
else
|
||||
{
|
||||
setStatus( Status::Ok );
|
||||
}
|
||||
emit statusReady();
|
||||
}
|
||||
@ -134,7 +141,7 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
m_queue = new LoaderQueue( this );
|
||||
m_queue->append( SourceItem::makeSourceItem( groupsUrlVariant.toString(), configurationMap ) );
|
||||
}
|
||||
else if ( groupsUrlVariant.type() == QVariant::StringList )
|
||||
else if ( groupsUrlVariant.type() == QVariant::List )
|
||||
{
|
||||
m_queue = new LoaderQueue( this );
|
||||
for ( const auto& s : groupsUrlVariant.toStringList() )
|
||||
@ -142,10 +149,11 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
m_queue->append( SourceItem::makeSourceItem( s, configurationMap ) );
|
||||
}
|
||||
}
|
||||
if ( m_queue )
|
||||
if ( m_queue && m_queue->count() > 0 )
|
||||
{
|
||||
cDebug() << "Loading netinstall from" << m_queue->count() << "alternate sources.";
|
||||
connect( m_queue, &LoaderQueue::done, this, &Config::loadingDone );
|
||||
QMetaObject::invokeMethod( m_queue, "fetchNext", Qt::QueuedConnection );
|
||||
m_queue->load();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,9 @@ public:
|
||||
FailedBadConfiguration,
|
||||
FailedInternalError,
|
||||
FailedNetworkError,
|
||||
FailedBadData
|
||||
FailedBadData,
|
||||
FailedNoData
|
||||
|
||||
};
|
||||
|
||||
QString status() const;
|
||||
|
@ -20,6 +20,32 @@
|
||||
#include <QNetworkReply>
|
||||
#include <QTimer>
|
||||
|
||||
/** @brief Call fetchNext() on the queue if it can
|
||||
*
|
||||
* On destruction, a new call to fetchNext() is queued, so that
|
||||
* the queue continues loading. Calling release() before the
|
||||
* destructor skips the fetchNext(), ending the queue-loading.
|
||||
*/
|
||||
class FetchNextUnless
|
||||
{
|
||||
public:
|
||||
FetchNextUnless( LoaderQueue* q )
|
||||
: m_q( q )
|
||||
{
|
||||
}
|
||||
~FetchNextUnless()
|
||||
{
|
||||
if ( m_q )
|
||||
{
|
||||
QMetaObject::invokeMethod( m_q, "fetchNext", Qt::QueuedConnection );
|
||||
}
|
||||
}
|
||||
void release() { m_q = nullptr; }
|
||||
|
||||
private:
|
||||
LoaderQueue* m_q = nullptr;
|
||||
};
|
||||
|
||||
SourceItem
|
||||
SourceItem::makeSourceItem( const QString& groupsUrl, const QVariantMap& configurationMap )
|
||||
{
|
||||
@ -45,6 +71,13 @@ LoaderQueue::append( SourceItem&& i )
|
||||
m_queue.append( std::move( i ) );
|
||||
}
|
||||
|
||||
void
|
||||
LoaderQueue::load()
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "fetchNext", Qt::QueuedConnection );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LoaderQueue::fetchNext()
|
||||
{
|
||||
@ -67,13 +100,16 @@ LoaderQueue::fetchNext()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LoaderQueue::fetch( const QUrl& url )
|
||||
{
|
||||
FetchNextUnless next( this );
|
||||
|
||||
if ( !url.isValid() )
|
||||
{
|
||||
m_config->setStatus( Config::Status::FailedBadConfiguration );
|
||||
cDebug() << "Invalid URL" << url;
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace CalamaresUtils::Network;
|
||||
@ -85,42 +121,20 @@ LoaderQueue::fetch( const QUrl& url )
|
||||
|
||||
if ( !reply )
|
||||
{
|
||||
cDebug() << Logger::Continuation << "request failed immediately.";
|
||||
cDebug() << Logger::SubEntry << "Request failed immediately.";
|
||||
// If nobody sets a different status, this will remain
|
||||
m_config->setStatus( Config::Status::FailedBadConfiguration );
|
||||
}
|
||||
else
|
||||
{
|
||||
// When the network request is done, **then** we might
|
||||
// do the next item from the queue, so don't call fetchNext() now.
|
||||
next.release();
|
||||
m_reply = reply;
|
||||
connect( reply, &QNetworkReply::finished, this, &LoaderQueue::dataArrived );
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Call fetchNext() on the queue if it can
|
||||
*
|
||||
* On destruction, a new call to fetchNext() is queued, so that
|
||||
* the queue continues loading. Calling release() before the
|
||||
* destructor skips the fetchNext(), ending the queue-loading.
|
||||
*/
|
||||
class FetchNextUnless
|
||||
{
|
||||
public:
|
||||
FetchNextUnless( LoaderQueue* q )
|
||||
: m_q( q )
|
||||
{
|
||||
}
|
||||
~FetchNextUnless()
|
||||
{
|
||||
if ( m_q )
|
||||
{
|
||||
QMetaObject::invokeMethod( m_q, "fetchNext", Qt::QueuedConnection );
|
||||
}
|
||||
}
|
||||
void release() { m_q = nullptr; }
|
||||
|
||||
private:
|
||||
LoaderQueue* m_q = nullptr;
|
||||
};
|
||||
|
||||
void
|
||||
LoaderQueue::dataArrived()
|
||||
{
|
||||
|
@ -41,7 +41,14 @@ struct SourceItem
|
||||
static SourceItem makeSourceItem( const QString& groupsUrl, const QVariantMap& configurationMap );
|
||||
};
|
||||
|
||||
|
||||
/** @brief Queue of source items to load
|
||||
*
|
||||
* Queue things up by calling append() and then kick things off
|
||||
* by calling load(). This will try to load the items, in order;
|
||||
* the first one that succeeds will end the loading process.
|
||||
*
|
||||
* Signal done() is emitted when done (also when all of the items fail).
|
||||
*/
|
||||
class LoaderQueue : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -49,9 +56,12 @@ public:
|
||||
LoaderQueue( Config* parent );
|
||||
|
||||
void append( SourceItem&& i );
|
||||
void fetchNext();
|
||||
int count() const { return m_queue.count(); }
|
||||
|
||||
public Q_SLOTS:
|
||||
void load();
|
||||
|
||||
void fetchNext();
|
||||
void fetch( const QUrl& url );
|
||||
void dataArrived();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user