Enhanced feed updates, still bugs maybe.

ˇ
This commit is contained in:
Martin Rotter 2016-08-24 08:26:33 +02:00
parent d2096c79e4
commit d4865ff143
4 changed files with 51 additions and 39 deletions

View File

@ -26,61 +26,81 @@
FeedDownloader::FeedDownloader(QObject *parent) FeedDownloader::FeedDownloader(QObject *parent)
: QObject(parent), m_threadPool(new QThreadPool(this)), m_results(FeedDownloadResults()), m_feedsUpdated(0), m_feedsToUpdate(0), : QObject(parent), m_feeds(QList<Feed*>()), m_mutex(new QMutex()), m_threadPool(new QThreadPool(this)),
m_feedsUpdating(0), m_feedsTotalCount(0), m_stopUpdate(false) { m_results(FeedDownloadResults()), m_feedsUpdated(0),
m_feedsUpdating(0), m_feedsTotalCount(0) {
qRegisterMetaType<FeedDownloadResults>("FeedDownloadResults"); qRegisterMetaType<FeedDownloadResults>("FeedDownloadResults");
m_threadPool->setMaxThreadCount(FEED_DOWNLOADER_MAX_THREADS); m_threadPool->setMaxThreadCount(FEED_DOWNLOADER_MAX_THREADS);
} }
FeedDownloader::~FeedDownloader() { FeedDownloader::~FeedDownloader() {
m_mutex->tryLock();
m_mutex->unlock();
delete m_mutex;
qDebug("Destroying FeedDownloader instance."); qDebug("Destroying FeedDownloader instance.");
} }
bool FeedDownloader::isUpdateRunning() const { bool FeedDownloader::isUpdateRunning() const {
return m_feedsToUpdate > 0 || m_feedsUpdating > 0; QMutexLocker locker(m_mutex);
return !m_feeds.isEmpty() || m_feedsUpdating > 0;
}
void FeedDownloader::updateAvailableFeeds() {
while (!m_feeds.isEmpty()) {
connect(m_feeds.first(), &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished,
(Qt::ConnectionType) (Qt::UniqueConnection | Qt::AutoConnection));
if (m_threadPool->tryStart(m_feeds.first())) {
m_feeds.removeFirst();
m_feedsUpdating++;
}
else {
// We want to start update of some feeds but all working threads are occupied.
break;
}
}
} }
void FeedDownloader::updateFeeds(const QList<Feed*> &feeds) { void FeedDownloader::updateFeeds(const QList<Feed*> &feeds) {
QMutexLocker locker(m_mutex);
if (feeds.isEmpty()) { if (feeds.isEmpty()) {
qDebug("No feeds to update in worker thread, aborting update."); qDebug("No feeds to update in worker thread, aborting update.");
finalizeUpdate(); finalizeUpdate();
return;
} }
else {
qDebug().nospace() << "Starting feed updates from worker in thread: \'" << QThread::currentThreadId() << "\'.";
qDebug().nospace() << "Starting feed updates from worker in thread: \'" << QThread::currentThreadId() << "\'."; m_feeds = feeds;
m_results.clear();
m_feedsUpdated = m_feedsUpdating = 0;
m_results.clear(); // Job starts now.
emit updateStarted();
m_feedsUpdated = 0; updateAvailableFeeds();
m_feedsUpdating = 0;
m_feedsToUpdate = feeds.size();
m_feedsTotalCount = m_feedsToUpdate;
// Job starts now.
emit updateStarted();
for (int i = 0; i < m_feedsTotalCount; i++) {
connect(feeds.at(i), &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished,
(Qt::ConnectionType) (Qt::UniqueConnection | Qt::AutoConnection));
m_threadPool->start(feeds.at(i));
m_feedsUpdating++;
m_feedsToUpdate--;
} }
} }
void FeedDownloader::stopRunningUpdate() { void FeedDownloader::stopRunningUpdate() {
//QMutexLocker locker(m_mutex);
m_threadPool->clear(); m_threadPool->clear();
m_feeds.clear();
} }
void FeedDownloader::oneFeedUpdateFinished(const QList<Message> &messages) { void FeedDownloader::oneFeedUpdateFinished(const QList<Message> &messages) {
QMutexLocker locker(m_mutex);
m_feedsUpdated++;
m_feedsUpdating--;
Feed *feed = qobject_cast<Feed*>(sender()); Feed *feed = qobject_cast<Feed*>(sender());
disconnect(feed, &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished); disconnect(feed, &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished);
m_feedsUpdated++; // Now, we check if there are any feeds we would like to update too.
m_feedsUpdating--; updateAvailableFeeds();
// Now make sure, that messages are actually stored to SQL in a locked state. // Now make sure, that messages are actually stored to SQL in a locked state.
qDebug().nospace() << "Saving messages of feed " qDebug().nospace() << "Saving messages of feed "
@ -100,7 +120,7 @@ void FeedDownloader::oneFeedUpdateFinished(const QList<Message> &messages) {
qDebug("Made progress in feed updates, total feeds count %d/%d (id of feed is %d).", m_feedsUpdated, m_feedsTotalCount, feed->id()); qDebug("Made progress in feed updates, total feeds count %d/%d (id of feed is %d).", m_feedsUpdated, m_feedsTotalCount, feed->id());
emit updateProgress(feed, m_feedsUpdated, m_feedsTotalCount); emit updateProgress(feed, m_feedsUpdated, m_feedsTotalCount);
if (m_threadPool->activeThreadCount() <= 0 || (m_feedsToUpdate <= 0 && m_feedsUpdating <= 0)) { if (m_feeds.isEmpty() && m_feedsUpdating <= 0) {
finalizeUpdate(); finalizeUpdate();
} }
} }
@ -108,9 +128,6 @@ void FeedDownloader::oneFeedUpdateFinished(const QList<Message> &messages) {
void FeedDownloader::finalizeUpdate() { void FeedDownloader::finalizeUpdate() {
qDebug().nospace() << "Finished feed updates in thread: \'" << QThread::currentThreadId() << "\'."; qDebug().nospace() << "Finished feed updates in thread: \'" << QThread::currentThreadId() << "\'.";
m_feedsToUpdate = 0;
m_feedsUpdating = 0;
m_results.sort(); m_results.sort();
// Update of feeds has finished. // Update of feeds has finished.

View File

@ -87,17 +87,17 @@ class FeedDownloader : public QObject {
void updateProgress(const Feed *feed, int current, int total); void updateProgress(const Feed *feed, int current, int total);
private: private:
void updateAvailableFeeds();
void finalizeUpdate(); void finalizeUpdate();
QList<Feed*> m_feeds;
QMutex *m_mutex;
QThreadPool *m_threadPool; QThreadPool *m_threadPool;
FeedDownloadResults m_results; FeedDownloadResults m_results;
int m_feedsUpdated; int m_feedsUpdated;
int m_feedsToUpdate;
int m_feedsUpdating; int m_feedsUpdating;
int m_feedsTotalCount; int m_feedsTotalCount;
bool m_stopUpdate;
}; };
#endif // FEEDDOWNLOADER_H #endif // FEEDDOWNLOADER_H

View File

@ -84,9 +84,7 @@ void FeedReader::updateFeeds(const QList<Feed*> &feeds) {
qRegisterMetaType<QList<Feed*> >("QList<Feed*>"); qRegisterMetaType<QList<Feed*> >("QList<Feed*>");
m_feedDownloader->moveToThread(m_feedDownloaderThread); m_feedDownloader->moveToThread(m_feedDownloaderThread);
connect(this, &FeedReader::feedsUpdateRequested, m_feedDownloader, &FeedDownloader::updateFeeds);
connect(m_feedDownloaderThread, &QThread::finished, m_feedDownloaderThread, &QThread::deleteLater); connect(m_feedDownloaderThread, &QThread::finished, m_feedDownloaderThread, &QThread::deleteLater);
connect(m_feedDownloader, &FeedDownloader::updateFinished, this, &FeedReader::feedUpdatesFinished); connect(m_feedDownloader, &FeedDownloader::updateFinished, this, &FeedReader::feedUpdatesFinished);
connect(m_feedDownloader, &FeedDownloader::updateProgress, this, &FeedReader::feedUpdatesProgress); connect(m_feedDownloader, &FeedDownloader::updateProgress, this, &FeedReader::feedUpdatesProgress);
connect(m_feedDownloader, &FeedDownloader::updateStarted, this, &FeedReader::feedUpdatesStarted); connect(m_feedDownloader, &FeedDownloader::updateStarted, this, &FeedReader::feedUpdatesStarted);
@ -96,7 +94,7 @@ void FeedReader::updateFeeds(const QList<Feed*> &feeds) {
m_feedDownloaderThread->start(); m_feedDownloaderThread->start();
} }
emit feedsUpdateRequested(feeds); QMetaObject::invokeMethod(m_feedDownloader, "updateFeeds", Q_ARG(QList<Feed*>, feeds));
} }
void FeedReader::updateAutoUpdateStatus() { void FeedReader::updateAutoUpdateStatus() {
@ -126,7 +124,7 @@ void FeedReader::updateAllFeeds() {
void FeedReader::stopRunningFeedUpdate() { void FeedReader::stopRunningFeedUpdate() {
if (m_feedDownloader != nullptr) { if (m_feedDownloader != nullptr) {
m_feedDownloader->stopRunningUpdate(); QMetaObject::invokeMethod(m_feedDownloader, "stopRunningUpdate");
} }
} }

View File

@ -72,9 +72,6 @@ class FeedReader : public QObject {
void executeNextAutoUpdate(); void executeNextAutoUpdate();
signals: signals:
// Emitted when model requests update of some feeds.
void feedsUpdateRequested(QList<Feed*> feeds);
void feedUpdatesStarted(); void feedUpdatesStarted();
void feedUpdatesFinished(FeedDownloadResults updated_feeds); void feedUpdatesFinished(FeedDownloadResults updated_feeds);
void feedUpdatesProgress(const Feed *feed, int current, int total); void feedUpdatesProgress(const Feed *feed, int current, int total);