Improved logging (now with time), preparation for #71.
This commit is contained in:
parent
e2fa0aeea6
commit
fcab295ab8
@ -326,7 +326,8 @@ HEADERS += src/core/feeddownloader.h \
|
||||
src/services/standard/atomparser.h \
|
||||
src/services/standard/feedparser.h \
|
||||
src/services/standard/rdfparser.h \
|
||||
src/services/standard/rssparser.h
|
||||
src/services/standard/rssparser.h \
|
||||
src/miscellaneous/serviceoperator.h
|
||||
|
||||
SOURCES += src/core/feeddownloader.cpp \
|
||||
src/core/feedsmodel.cpp \
|
||||
@ -444,7 +445,8 @@ SOURCES += src/core/feeddownloader.cpp \
|
||||
src/services/standard/atomparser.cpp \
|
||||
src/services/standard/feedparser.cpp \
|
||||
src/services/standard/rdfparser.cpp \
|
||||
src/services/standard/rssparser.cpp
|
||||
src/services/standard/rssparser.cpp \
|
||||
src/miscellaneous/serviceoperator.cpp
|
||||
|
||||
FORMS += src/gui/toolbareditor.ui \
|
||||
src/network-web/downloaditem.ui \
|
||||
|
@ -373,7 +373,7 @@ void Application::onAboutToQuit() {
|
||||
system()->removeTrolltechJunkRegistryKeys();
|
||||
#endif
|
||||
|
||||
qApp->feedReader()->stop();
|
||||
qApp->feedReader()->quit();
|
||||
database()->saveDatabase();
|
||||
|
||||
if (mainForm() != nullptr) {
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
|
||||
|
||||
Debugging::Debugging() {
|
||||
@ -31,13 +33,18 @@ Debugging::Debugging() {
|
||||
void Debugging::performLog(const char *message, QtMsgType type, const char *file, const char *function, int line) {
|
||||
const char *type_string = typeToString(type);
|
||||
|
||||
std::time_t t = std::time(nullptr);
|
||||
char mbstr[32];
|
||||
|
||||
std::strftime(mbstr, sizeof(mbstr), "%y/%d/%m %H:%M:%S", std::localtime(&t));
|
||||
|
||||
// Write to console.
|
||||
if (file == 0 || function == 0 || line < 0) {
|
||||
fprintf(stderr, "[%s] %s: %s\n", APP_LOW_NAME, type_string, message);
|
||||
fprintf(stderr, "[%s] %s: %s (%s)\n", APP_LOW_NAME, type_string, message, mbstr);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "[%s] %s\n Type: %s\n File: %s (line %d)\n Function: %s\n\n",
|
||||
APP_LOW_NAME, message, type_string, file, line, function);
|
||||
fprintf(stderr, "[%s] %s (%s)\n Type: %s\n File: %s (line %d)\n Function: %s\n\n",
|
||||
APP_LOW_NAME, message, mbstr, type_string, file, line, function);
|
||||
}
|
||||
|
||||
if (type == QtFatalMsg) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "services/standard/standardserviceentrypoint.h"
|
||||
#include "services/owncloud/owncloudserviceentrypoint.h"
|
||||
#include "services/tt-rss/ttrssserviceentrypoint.h"
|
||||
#include "services/abstract/serviceroot.h"
|
||||
|
||||
#include "core/feedsmodel.h"
|
||||
#include "core/feedsproxymodel.h"
|
||||
@ -32,10 +33,12 @@
|
||||
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QtConcurrent/QtConcurrentRun>
|
||||
|
||||
|
||||
FeedReader::FeedReader(QObject *parent)
|
||||
: QObject(parent), m_feedServices(QList<ServiceEntryPoint*>()), m_autoUpdateTimer(new QTimer(this)),
|
||||
: QObject(parent), m_feedServices(QList<ServiceEntryPoint*>()),
|
||||
m_cacheSaveFutureWatcher(QFutureWatcher<void>()), m_autoUpdateTimer(new QTimer(this)),
|
||||
m_feedDownloaderThread(nullptr), m_feedDownloader(nullptr),
|
||||
m_dbCleanerThread(nullptr), m_dbCleaner(nullptr) {
|
||||
m_feedsModel = new FeedsModel(this);
|
||||
@ -43,8 +46,10 @@ FeedReader::FeedReader(QObject *parent)
|
||||
m_messagesModel = new MessagesModel(this);
|
||||
m_messagesProxyModel = new MessagesProxyModel(m_messagesModel, this);
|
||||
|
||||
connect(&m_cacheSaveFutureWatcher, &QFutureWatcher<void>::finished, this, &FeedReader::asyncCacheSaveFinished);
|
||||
connect(m_autoUpdateTimer, &QTimer::timeout, this, &FeedReader::executeNextAutoUpdate);
|
||||
updateAutoUpdateStatus();
|
||||
asyncCacheSaveFinished();
|
||||
|
||||
if (qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::FeedsUpdateOnStartup)).toBool()) {
|
||||
qDebug("Requesting update for all feeds on application startup.");
|
||||
@ -209,11 +214,60 @@ void FeedReader::executeNextAutoUpdate() {
|
||||
}
|
||||
}
|
||||
|
||||
void FeedReader::stop() {
|
||||
void FeedReader::checkServicesForAsyncOperations() {
|
||||
checkServicesForAsyncOperations(false);
|
||||
}
|
||||
|
||||
void FeedReader::checkServicesForAsyncOperations(bool wait_for_future) {
|
||||
if (m_cacheSaveFutureWatcher.future().isStarted() || m_cacheSaveFutureWatcher.future().isRunning()) {
|
||||
qDebug("Previous future is still running or was already started.");
|
||||
|
||||
|
||||
// If we want to wait for future synchronously, we want to make sure that
|
||||
// we save all cached data (app exit).
|
||||
if (wait_for_future) {
|
||||
qWarning("Waiting for previously started saving of cached service data.");
|
||||
m_cacheSaveFutureWatcher.future().waitForFinished();
|
||||
}
|
||||
else {
|
||||
qWarning("Some cached service data are being saved now, so aborting this saving cycle.");
|
||||
// Some cache saving is now running.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QFuture<void> future = QtConcurrent::run([&] {
|
||||
foreach (ServiceRoot *service, m_feedsModel->serviceRoots()) {
|
||||
// Store any cached data.
|
||||
service->saveAllCachedData();
|
||||
}
|
||||
});
|
||||
|
||||
if (wait_for_future) {
|
||||
qDebug("Waiting for saving of cached service data to finish.");
|
||||
future.waitForFinished();
|
||||
}
|
||||
else {
|
||||
m_cacheSaveFutureWatcher.setFuture(future);
|
||||
}
|
||||
}
|
||||
|
||||
void FeedReader::asyncCacheSaveFinished() {
|
||||
qDebug("I will start next check for cached service data in 30 seconds.");
|
||||
|
||||
QTimer::singleShot(30000, [&] {
|
||||
qDebug("Starting next check for cached service data in NOW.");
|
||||
checkServicesForAsyncOperations(false);
|
||||
});
|
||||
}
|
||||
|
||||
void FeedReader::quit() {
|
||||
if (m_autoUpdateTimer->isActive()) {
|
||||
m_autoUpdateTimer->stop();
|
||||
}
|
||||
|
||||
checkServicesForAsyncOperations(true);
|
||||
|
||||
// Close worker threads.
|
||||
if (m_feedDownloaderThread != nullptr && m_feedDownloaderThread->isRunning()) {
|
||||
m_feedDownloader->stopRunningUpdate();
|
||||
|
@ -23,12 +23,15 @@
|
||||
#include "services/abstract/feed.h"
|
||||
#include "core/feeddownloader.h"
|
||||
|
||||
#include <QFutureWatcher>
|
||||
|
||||
|
||||
class FeedsModel;
|
||||
class MessagesModel;
|
||||
class MessagesProxyModel;
|
||||
class FeedsProxyModel;
|
||||
class ServiceEntryPoint;
|
||||
class ServiceOperator;
|
||||
class DatabaseCleaner;
|
||||
class QTimer;
|
||||
|
||||
@ -69,11 +72,14 @@ class FeedReader : public QObject {
|
||||
// Schedules all feeds from all accounts for update.
|
||||
void updateAllFeeds();
|
||||
void stopRunningFeedUpdate();
|
||||
void stop();
|
||||
void quit();
|
||||
|
||||
private slots:
|
||||
// Is executed when next auto-update round could be done.
|
||||
void executeNextAutoUpdate();
|
||||
void checkServicesForAsyncOperations();
|
||||
void checkServicesForAsyncOperations(bool wait_for_future);
|
||||
void asyncCacheSaveFinished();
|
||||
|
||||
signals:
|
||||
void feedUpdatesStarted();
|
||||
@ -88,12 +94,16 @@ class FeedReader : public QObject {
|
||||
MessagesModel *m_messagesModel;
|
||||
MessagesProxyModel *m_messagesProxyModel;
|
||||
|
||||
QFutureWatcher<void> m_cacheSaveFutureWatcher;
|
||||
|
||||
// Auto-update stuff.
|
||||
QTimer *m_autoUpdateTimer;
|
||||
bool m_globalAutoUpdateEnabled;
|
||||
int m_globalAutoUpdateInitialInterval;
|
||||
int m_globalAutoUpdateRemainingInterval;
|
||||
|
||||
ServiceOperator *m_serviceOperator;
|
||||
|
||||
QThread *m_feedDownloaderThread;
|
||||
FeedDownloader *m_feedDownloader;
|
||||
|
||||
|
25
src/miscellaneous/serviceoperator.cpp
Executable file
25
src/miscellaneous/serviceoperator.cpp
Executable file
@ -0,0 +1,25 @@
|
||||
// This file is part of RSS Guard.
|
||||
//
|
||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||
//
|
||||
// RSS Guard is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// RSS Guard is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "miscellaneous/serviceoperator.h"
|
||||
|
||||
|
||||
ServiceOperator::ServiceOperator(QObject *parent) : QObject(parent) {
|
||||
}
|
||||
|
||||
ServiceOperator::~ServiceOperator() {
|
||||
}
|
36
src/miscellaneous/serviceoperator.h
Executable file
36
src/miscellaneous/serviceoperator.h
Executable file
@ -0,0 +1,36 @@
|
||||
// This file is part of RSS Guard.
|
||||
//
|
||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||
//
|
||||
// RSS Guard is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// RSS Guard is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef SERVICEOPERATOR_H
|
||||
#define SERVICEOPERATOR_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
|
||||
class ServiceOperator : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ServiceOperator(QObject *parent = 0);
|
||||
virtual ~ServiceOperator();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // SERVICEOPERATOR_H
|
@ -192,6 +192,9 @@ QList<Message> ServiceRoot::undeletedMessages() const {
|
||||
return DatabaseQueries::getUndeletedMessagesForAccount(database, accountId());
|
||||
}
|
||||
|
||||
void ServiceRoot::saveAllCachedData() {
|
||||
}
|
||||
|
||||
void ServiceRoot::itemChanged(const QList<RootItem*> &items) {
|
||||
emit dataChanged(items);
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ class ServiceRoot : public RootItem {
|
||||
// NOTE: Caller does NOT take ownership of created menu!
|
||||
virtual QList<QAction*> addItemMenu();
|
||||
|
||||
// Returns actions to display as context menu.
|
||||
QList<QAction*> contextMenu();
|
||||
|
||||
// Returns list of specific actions to be shown in main window menu
|
||||
@ -83,6 +84,10 @@ class ServiceRoot : public RootItem {
|
||||
virtual void start(bool freshly_activated) = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
// Is called in short intervals in worker thread.
|
||||
// Service can save its cached data (if any) here.
|
||||
virtual void saveAllCachedData();
|
||||
|
||||
// Account ID corresponds with DB attribute Accounts (id).
|
||||
int accountId() const;
|
||||
void setAccountId(int account_id);
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "services/owncloud/gui/formeditowncloudaccount.h"
|
||||
#include "services/owncloud/gui/formowncloudfeeddetails.h"
|
||||
|
||||
#include <QThread>
|
||||
|
||||
|
||||
OwnCloudServiceRoot::OwnCloudServiceRoot(RootItem *parent)
|
||||
: ServiceRoot(parent), m_recycleBin(new OwnCloudRecycleBin(this)),
|
||||
@ -195,6 +197,10 @@ void OwnCloudServiceRoot::saveAccountDataToDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
void OwnCloudServiceRoot::saveAllCachedData() {
|
||||
QThread::msleep(2000);
|
||||
}
|
||||
|
||||
void OwnCloudServiceRoot::addNewFeed(const QString &url) {
|
||||
if (!qApp->feedUpdateLock()->tryLock()) {
|
||||
// Lock was not obtained because
|
||||
|
@ -51,6 +51,8 @@ class OwnCloudServiceRoot : public ServiceRoot {
|
||||
void updateTitle();
|
||||
void saveAccountDataToDatabase();
|
||||
|
||||
void saveAllCachedData();
|
||||
|
||||
public slots:
|
||||
void addNewFeed(const QString &url);
|
||||
void addNewCategory();
|
||||
|
Loading…
x
Reference in New Issue
Block a user