From 84c2a2b2a24591674450acfadc81c38a13819725 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 31 May 2016 07:19:22 +0200 Subject: [PATCH] First experiment - working parallels. --- CMakeLists.txt | 4 +- src/core/feeddownloader.cpp | 88 +++++++++++++++++++++++++--------- src/core/feeddownloader.h | 11 +++++ src/services/abstract/feed.cpp | 5 ++ src/services/abstract/feed.h | 9 +++- 5 files changed, 91 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e9b56628..9db7c86b4 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,8 +61,8 @@ project(rssguard) set(APP_NAME "RSS Guard") set(APP_LOW_NAME "rssguard") -set(APP_VERSION "3.2.5") -set(FILE_VERSION "3,2,5,0") +set(APP_VERSION "3.3.0") +set(FILE_VERSION "3,3,0,0") set(APP_AUTHOR "Martin Rotter") set(APP_URL "http://bitbucket.org/skunkos/rssguard") set(APP_URL_ISSUES "http://bitbucket.org/skunkos/rssguard/issues") diff --git a/src/core/feeddownloader.cpp b/src/core/feeddownloader.cpp index 3fe474133..b843e0ce8 100755 --- a/src/core/feeddownloader.cpp +++ b/src/core/feeddownloader.cpp @@ -23,9 +23,10 @@ #include #include #include +#include -FeedDownloader::FeedDownloader(QObject *parent) : QObject(parent), m_isUpdateRunning(false), m_stopUpdate(false) { +FeedDownloader::FeedDownloader(QObject *parent) : QObject(parent), m_results(FeedDownloadResults()), m_isUpdateRunning(false), m_stopUpdate(false) { qRegisterMetaType("FeedDownloadResults"); } @@ -45,46 +46,87 @@ void FeedDownloader::updateFeeds(const QList &feeds) { m_isUpdateRunning = true; m_stopUpdate = false; + m_results.clear(); + + m_feedsUpdating = 0; + m_feedsToUpdate = feeds.size(); + m_totalFeedsCount = m_feedsToUpdate; + // Job starts now. emit started(); FeedDownloadResults results; - for (int i = 0, total = feeds.size(); i < total; i++) { + for (int i = 0, total = m_totalFeedsCount; i < total; i++) { if (m_stopUpdate) { qDebug("Stopping batch feed update now."); + m_feedsToUpdate = 0; + + if (m_feedsUpdating <= 0) { + qDebug().nospace() << "Finished feed updates in thread: \'" << QThread::currentThreadId() << "\'."; + + m_results.sort(); + + // Make sure that there is not "stop" action pending. + m_isUpdateRunning = false; + m_stopUpdate = false; + + // Update of feeds has finished. + // NOTE: This means that now "update lock" can be unlocked + // and feeds can be added/edited/deleted and application + // can eventually quit. + emit finished(m_results); + } + break; } - int updated_messages = feeds.at(i)->update(); + connect(feeds.at(i), SIGNAL(updated(int)), this, SLOT(oneFeedUpdateFinished(int)), + (Qt::ConnectionType) (Qt::UniqueConnection | Qt::AutoConnection)); + QThreadPool::globalInstance()->start(feeds.at(i)); - if (updated_messages > 0) { - results.appendUpdatedFeed(QPair(feeds.at(i)->title(), updated_messages)); - } - - qDebug("Made progress in feed updates: %d/%d (id of feed is %d).", i + 1, total, feeds.at(i)->id()); - emit progress(feeds.at(i), i + 1, total); + m_feedsUpdating++; + m_feedsToUpdate--; } - - qDebug().nospace() << "Finished feed updates in thread: \'" << QThread::currentThreadId() << "\'."; - - results.sort(); - - // Make sure that there is not "stop" action pending. - m_isUpdateRunning = false; - m_stopUpdate = false; - - // Update of feeds has finished. - // NOTE: This means that now "update lock" can be unlocked - // and feeds can be added/edited/deleted and application - // can eventually quit. - emit finished(results); } void FeedDownloader::stopRunningUpdate() { m_stopUpdate = true; } +void FeedDownloader::oneFeedUpdateFinished(int updated_messages) { + Feed *feed = qobject_cast(sender()); + + disconnect(feed, SIGNAL(updated(int)), + this, SLOT(oneFeedUpdateFinished(int))); + + if (updated_messages > 0) { + m_results.appendUpdatedFeed(QPair(feed->title(), updated_messages)); + } + + qDebug("Made progress in feed updates, total feeds count %d (id of feed is %d).", + m_totalFeedsCount, feed->id()); + emit progress(feed, m_totalFeedsCount - m_feedsToUpdate, m_totalFeedsCount); + + m_feedsUpdating--; + + if (m_feedsToUpdate == 0 && m_feedsUpdating == 0) { + qDebug().nospace() << "Finished feed updates in thread: \'" << QThread::currentThreadId() << "\'."; + + m_results.sort(); + + // Make sure that there is not "stop" action pending. + m_isUpdateRunning = false; + m_stopUpdate = false; + + // Update of feeds has finished. + // NOTE: This means that now "update lock" can be unlocked + // and feeds can be added/edited/deleted and application + // can eventually quit. + emit finished(m_results); + } +} + FeedDownloadResults::FeedDownloadResults() : m_updatedFeeds(QList >()) { } diff --git a/src/core/feeddownloader.h b/src/core/feeddownloader.h index 892f61127..fe9210c7a 100755 --- a/src/core/feeddownloader.h +++ b/src/core/feeddownloader.h @@ -38,6 +38,10 @@ class FeedDownloadResults { static bool lessThan(const QPair &lhs, const QPair &rhs); + inline void clear() { + m_updatedFeeds.clear(); + } + private: // QString represents title if the feed, int represents count of newly downloaded messages. QList > m_updatedFeeds; @@ -65,6 +69,9 @@ class FeedDownloader : public QObject { // Stops running update. void stopRunningUpdate(); + private slots: + void oneFeedUpdateFinished(int updated_messages); + signals: // Emitted if feed updates started. void started(); @@ -80,6 +87,10 @@ class FeedDownloader : public QObject { void progress(const Feed *feed, int current, int total); private: + FeedDownloadResults m_results; + int m_feedsToUpdate; + int m_feedsUpdating; + int m_totalFeedsCount; bool m_isUpdateRunning; bool m_stopUpdate; }; diff --git a/src/services/abstract/feed.cpp b/src/services/abstract/feed.cpp index 6ca0b6a56..6162ebcc4 100755 --- a/src/services/abstract/feed.cpp +++ b/src/services/abstract/feed.cpp @@ -29,6 +29,7 @@ Feed::Feed(RootItem *parent) m_autoUpdateInitialInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_autoUpdateRemainingInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_totalCount(0), m_unreadCount(0) { setKind(RootItemKind::Feed); + setAutoDelete(false); } Feed::~Feed() { @@ -129,6 +130,10 @@ void Feed::updateCounts(bool including_total_count) { setCountOfUnreadMessages(DatabaseQueries::getMessageCountsForFeed(database, customId(), account_id, false)); } +void Feed::run() { + emit updated(update()); +} + int Feed::updateMessages(const QList &messages) { int custom_id = customId(); int account_id = getParentServiceRoot()->accountId(); diff --git a/src/services/abstract/feed.h b/src/services/abstract/feed.h index be9141b6c..b86c90580 100755 --- a/src/services/abstract/feed.h +++ b/src/services/abstract/feed.h @@ -23,10 +23,11 @@ #include "core/message.h" #include +#include // Base class for "feed" nodes. -class Feed : public RootItem { +class Feed : public RootItem, public QRunnable { Q_OBJECT public: @@ -96,12 +97,18 @@ class Feed : public RootItem { void updateCounts(bool including_total_count); + // Runs update in thread (thread pooled). + void run(); + protected: virtual QList obtainNewMessages() = 0; private: int updateMessages(const QList &messages); + signals: + void updated(int updated_messages); + private: QString m_url; Status m_status;