Avoid race condition when adding feed

When adding a feed and simultaneously starting a feed update, a race
condition could happen where the feed update would catch up with the
feed adding, and start adding and marking old episodes as new before
the original addFeed method would reach them.
This commit is contained in:
Bart De Vries 2021-04-26 16:58:22 +02:00
parent 0d275b8400
commit f2c6c3fae2
2 changed files with 41 additions and 33 deletions

View File

@ -37,6 +37,45 @@ Fetcher::Fetcher()
}
void Fetcher::fetch(const QString &url)
{
QStringList urls(url);
fetch(urls);
}
void Fetcher::fetch(const QStringList &urls)
{
if (m_updating) return; // update is already running, do nothing
m_updating = true;
m_updateProgress = 0;
m_updateTotal = urls.count();
connect(this, &Fetcher::updateProgressChanged, this, &Fetcher::updateMonitor);
Q_EMIT updatingChanged(m_updating);
Q_EMIT updateProgressChanged(m_updateProgress);
Q_EMIT updateTotalChanged(m_updateTotal);
for (int i=0; i<urls.count(); i++) {
retrieveFeed(urls[i]);
}
}
void Fetcher::fetchAll()
{
QStringList urls;
QSqlQuery query;
query.prepare(QStringLiteral("SELECT url FROM Feeds;"));
Database::instance().execute(query);
while (query.next()) {
urls += query.value(0).toString();;
}
if (urls.count() > 0)
fetch(urls);
else
return; // no feeds in database
}
void Fetcher::retrieveFeed(const QString &url)
{
qDebug() << "Starting to fetch" << url;
@ -62,39 +101,6 @@ void Fetcher::fetch(const QString &url)
});
}
void Fetcher::fetch(const QStringList &urls)
{
if (m_updating) return; // update is already running, do nothing
m_updating = true;
m_updateProgress = 0;
m_updateTotal = urls.count();
connect(this, &Fetcher::updateProgressChanged, this, &Fetcher::updateMonitor);
Q_EMIT updatingChanged(m_updating);
Q_EMIT updateProgressChanged(m_updateProgress);
Q_EMIT updateTotalChanged(m_updateTotal);
for (int i=0; i<urls.count(); i++) {
fetch(urls[i]);
}
}
void Fetcher::fetchAll()
{
QStringList urls;
QSqlQuery query;
query.prepare(QStringLiteral("SELECT url FROM Feeds;"));
Database::instance().execute(query);
while (query.next()) {
urls += query.value(0).toString();;
}
if (urls.count() > 0)
fetch(urls);
else
return; // no feeds in database
}
void Fetcher::updateMonitor(int progress)
{
//qDebug() << "Update monitor" << progress << "/" << m_updateTotal;

View File

@ -27,6 +27,7 @@ public:
static Fetcher _instance;
return _instance;
}
Q_INVOKABLE void fetch(const QString &url);
Q_INVOKABLE void fetch(const QStringList &urls);
Q_INVOKABLE void fetchAll();
@ -56,6 +57,7 @@ private Q_SLOTS:
private:
Fetcher();
void retrieveFeed(const QString &url);
void processFeed(Syndication::FeedPtr feed, const QString &url);
bool processEntry(Syndication::ItemPtr entry, const QString &url, const bool &isNewFeed); // returns true if this is a new entry; false if it already existed
void processAuthor(const QString &url, const QString &entryId, const QString &authorName, const QString &authorUri, const QString &authorEmail);