[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:
|
case Status::FailedBadData:
|
||||||
return tr( "Network Installation. (Disabled: Received invalid groups data)" );
|
return tr( "Network Installation. (Disabled: Received invalid groups data)" );
|
||||||
case Status::FailedInternalError:
|
case Status::FailedInternalError:
|
||||||
return tr( "Network Installation. (Disabled: internal error)" );
|
return tr( "Network Installation. (Disabled: Internal error)" );
|
||||||
case Status::FailedNetworkError:
|
case Status::FailedNetworkError:
|
||||||
return tr( "Network Installation. (Disabled: Unable to fetch package lists, check your network connection)" );
|
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();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
@ -89,6 +91,11 @@ Config::loadGroupList( const QVariantList& groupData )
|
|||||||
if ( m_model->rowCount() < 1 )
|
if ( m_model->rowCount() < 1 )
|
||||||
{
|
{
|
||||||
cWarning() << "NetInstall groups data was empty.";
|
cWarning() << "NetInstall groups data was empty.";
|
||||||
|
setStatus( Status::FailedNoData );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setStatus( Status::Ok );
|
||||||
}
|
}
|
||||||
emit statusReady();
|
emit statusReady();
|
||||||
}
|
}
|
||||||
@ -134,7 +141,7 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
m_queue = new LoaderQueue( this );
|
m_queue = new LoaderQueue( this );
|
||||||
m_queue->append( SourceItem::makeSourceItem( groupsUrlVariant.toString(), configurationMap ) );
|
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 );
|
m_queue = new LoaderQueue( this );
|
||||||
for ( const auto& s : groupsUrlVariant.toStringList() )
|
for ( const auto& s : groupsUrlVariant.toStringList() )
|
||||||
@ -142,10 +149,11 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
m_queue->append( SourceItem::makeSourceItem( s, 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 );
|
connect( m_queue, &LoaderQueue::done, this, &Config::loadingDone );
|
||||||
QMetaObject::invokeMethod( m_queue, "fetchNext", Qt::QueuedConnection );
|
m_queue->load();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,9 @@ public:
|
|||||||
FailedBadConfiguration,
|
FailedBadConfiguration,
|
||||||
FailedInternalError,
|
FailedInternalError,
|
||||||
FailedNetworkError,
|
FailedNetworkError,
|
||||||
FailedBadData
|
FailedBadData,
|
||||||
|
FailedNoData
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QString status() const;
|
QString status() const;
|
||||||
|
@ -20,6 +20,32 @@
|
|||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QTimer>
|
#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
|
||||||
SourceItem::makeSourceItem( const QString& groupsUrl, const QVariantMap& configurationMap )
|
SourceItem::makeSourceItem( const QString& groupsUrl, const QVariantMap& configurationMap )
|
||||||
{
|
{
|
||||||
@ -45,6 +71,13 @@ LoaderQueue::append( SourceItem&& i )
|
|||||||
m_queue.append( std::move( i ) );
|
m_queue.append( std::move( i ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LoaderQueue::load()
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod( this, "fetchNext", Qt::QueuedConnection );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LoaderQueue::fetchNext()
|
LoaderQueue::fetchNext()
|
||||||
{
|
{
|
||||||
@ -67,13 +100,16 @@ LoaderQueue::fetchNext()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LoaderQueue::fetch( const QUrl& url )
|
LoaderQueue::fetch( const QUrl& url )
|
||||||
{
|
{
|
||||||
|
FetchNextUnless next( this );
|
||||||
|
|
||||||
if ( !url.isValid() )
|
if ( !url.isValid() )
|
||||||
{
|
{
|
||||||
m_config->setStatus( Config::Status::FailedBadConfiguration );
|
m_config->setStatus( Config::Status::FailedBadConfiguration );
|
||||||
|
cDebug() << "Invalid URL" << url;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace CalamaresUtils::Network;
|
using namespace CalamaresUtils::Network;
|
||||||
@ -85,42 +121,20 @@ LoaderQueue::fetch( const QUrl& url )
|
|||||||
|
|
||||||
if ( !reply )
|
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 );
|
m_config->setStatus( Config::Status::FailedBadConfiguration );
|
||||||
}
|
}
|
||||||
else
|
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;
|
m_reply = reply;
|
||||||
connect( reply, &QNetworkReply::finished, this, &LoaderQueue::dataArrived );
|
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
|
void
|
||||||
LoaderQueue::dataArrived()
|
LoaderQueue::dataArrived()
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,14 @@ struct SourceItem
|
|||||||
static SourceItem makeSourceItem( const QString& groupsUrl, const QVariantMap& configurationMap );
|
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
|
class LoaderQueue : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -49,9 +56,12 @@ public:
|
|||||||
LoaderQueue( Config* parent );
|
LoaderQueue( Config* parent );
|
||||||
|
|
||||||
void append( SourceItem&& i );
|
void append( SourceItem&& i );
|
||||||
void fetchNext();
|
int count() const { return m_queue.count(); }
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
|
void load();
|
||||||
|
|
||||||
|
void fetchNext();
|
||||||
void fetch( const QUrl& url );
|
void fetch( const QUrl& url );
|
||||||
void dataArrived();
|
void dataArrived();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user