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/atomparser.h \
|
||||||
src/services/standard/feedparser.h \
|
src/services/standard/feedparser.h \
|
||||||
src/services/standard/rdfparser.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 \
|
SOURCES += src/core/feeddownloader.cpp \
|
||||||
src/core/feedsmodel.cpp \
|
src/core/feedsmodel.cpp \
|
||||||
@ -444,7 +445,8 @@ SOURCES += src/core/feeddownloader.cpp \
|
|||||||
src/services/standard/atomparser.cpp \
|
src/services/standard/atomparser.cpp \
|
||||||
src/services/standard/feedparser.cpp \
|
src/services/standard/feedparser.cpp \
|
||||||
src/services/standard/rdfparser.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 \
|
FORMS += src/gui/toolbareditor.ui \
|
||||||
src/network-web/downloaditem.ui \
|
src/network-web/downloaditem.ui \
|
||||||
|
@ -373,7 +373,7 @@ void Application::onAboutToQuit() {
|
|||||||
system()->removeTrolltechJunkRegistryKeys();
|
system()->removeTrolltechJunkRegistryKeys();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qApp->feedReader()->stop();
|
qApp->feedReader()->quit();
|
||||||
database()->saveDatabase();
|
database()->saveDatabase();
|
||||||
|
|
||||||
if (mainForm() != nullptr) {
|
if (mainForm() != nullptr) {
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <chrono>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
Debugging::Debugging() {
|
Debugging::Debugging() {
|
||||||
@ -31,13 +33,18 @@ Debugging::Debugging() {
|
|||||||
void Debugging::performLog(const char *message, QtMsgType type, const char *file, const char *function, int line) {
|
void Debugging::performLog(const char *message, QtMsgType type, const char *file, const char *function, int line) {
|
||||||
const char *type_string = typeToString(type);
|
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.
|
// Write to console.
|
||||||
if (file == 0 || function == 0 || line < 0) {
|
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 {
|
else {
|
||||||
fprintf(stderr, "[%s] %s\n Type: %s\n File: %s (line %d)\n Function: %s\n\n",
|
fprintf(stderr, "[%s] %s (%s)\n Type: %s\n File: %s (line %d)\n Function: %s\n\n",
|
||||||
APP_LOW_NAME, message, type_string, file, line, function);
|
APP_LOW_NAME, message, mbstr, type_string, file, line, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == QtFatalMsg) {
|
if (type == QtFatalMsg) {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "services/standard/standardserviceentrypoint.h"
|
#include "services/standard/standardserviceentrypoint.h"
|
||||||
#include "services/owncloud/owncloudserviceentrypoint.h"
|
#include "services/owncloud/owncloudserviceentrypoint.h"
|
||||||
#include "services/tt-rss/ttrssserviceentrypoint.h"
|
#include "services/tt-rss/ttrssserviceentrypoint.h"
|
||||||
|
#include "services/abstract/serviceroot.h"
|
||||||
|
|
||||||
#include "core/feedsmodel.h"
|
#include "core/feedsmodel.h"
|
||||||
#include "core/feedsproxymodel.h"
|
#include "core/feedsproxymodel.h"
|
||||||
@ -32,10 +33,12 @@
|
|||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
|
|
||||||
|
|
||||||
FeedReader::FeedReader(QObject *parent)
|
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_feedDownloaderThread(nullptr), m_feedDownloader(nullptr),
|
||||||
m_dbCleanerThread(nullptr), m_dbCleaner(nullptr) {
|
m_dbCleanerThread(nullptr), m_dbCleaner(nullptr) {
|
||||||
m_feedsModel = new FeedsModel(this);
|
m_feedsModel = new FeedsModel(this);
|
||||||
@ -43,8 +46,10 @@ FeedReader::FeedReader(QObject *parent)
|
|||||||
m_messagesModel = new MessagesModel(this);
|
m_messagesModel = new MessagesModel(this);
|
||||||
m_messagesProxyModel = new MessagesProxyModel(m_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);
|
connect(m_autoUpdateTimer, &QTimer::timeout, this, &FeedReader::executeNextAutoUpdate);
|
||||||
updateAutoUpdateStatus();
|
updateAutoUpdateStatus();
|
||||||
|
asyncCacheSaveFinished();
|
||||||
|
|
||||||
if (qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::FeedsUpdateOnStartup)).toBool()) {
|
if (qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::FeedsUpdateOnStartup)).toBool()) {
|
||||||
qDebug("Requesting update for all feeds on application startup.");
|
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()) {
|
if (m_autoUpdateTimer->isActive()) {
|
||||||
m_autoUpdateTimer->stop();
|
m_autoUpdateTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkServicesForAsyncOperations(true);
|
||||||
|
|
||||||
// Close worker threads.
|
// Close worker threads.
|
||||||
if (m_feedDownloaderThread != nullptr && m_feedDownloaderThread->isRunning()) {
|
if (m_feedDownloaderThread != nullptr && m_feedDownloaderThread->isRunning()) {
|
||||||
m_feedDownloader->stopRunningUpdate();
|
m_feedDownloader->stopRunningUpdate();
|
||||||
|
@ -23,12 +23,15 @@
|
|||||||
#include "services/abstract/feed.h"
|
#include "services/abstract/feed.h"
|
||||||
#include "core/feeddownloader.h"
|
#include "core/feeddownloader.h"
|
||||||
|
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
|
|
||||||
class FeedsModel;
|
class FeedsModel;
|
||||||
class MessagesModel;
|
class MessagesModel;
|
||||||
class MessagesProxyModel;
|
class MessagesProxyModel;
|
||||||
class FeedsProxyModel;
|
class FeedsProxyModel;
|
||||||
class ServiceEntryPoint;
|
class ServiceEntryPoint;
|
||||||
|
class ServiceOperator;
|
||||||
class DatabaseCleaner;
|
class DatabaseCleaner;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
|
|
||||||
@ -69,11 +72,14 @@ class FeedReader : public QObject {
|
|||||||
// Schedules all feeds from all accounts for update.
|
// Schedules all feeds from all accounts for update.
|
||||||
void updateAllFeeds();
|
void updateAllFeeds();
|
||||||
void stopRunningFeedUpdate();
|
void stopRunningFeedUpdate();
|
||||||
void stop();
|
void quit();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// Is executed when next auto-update round could be done.
|
// Is executed when next auto-update round could be done.
|
||||||
void executeNextAutoUpdate();
|
void executeNextAutoUpdate();
|
||||||
|
void checkServicesForAsyncOperations();
|
||||||
|
void checkServicesForAsyncOperations(bool wait_for_future);
|
||||||
|
void asyncCacheSaveFinished();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void feedUpdatesStarted();
|
void feedUpdatesStarted();
|
||||||
@ -88,12 +94,16 @@ class FeedReader : public QObject {
|
|||||||
MessagesModel *m_messagesModel;
|
MessagesModel *m_messagesModel;
|
||||||
MessagesProxyModel *m_messagesProxyModel;
|
MessagesProxyModel *m_messagesProxyModel;
|
||||||
|
|
||||||
|
QFutureWatcher<void> m_cacheSaveFutureWatcher;
|
||||||
|
|
||||||
// Auto-update stuff.
|
// Auto-update stuff.
|
||||||
QTimer *m_autoUpdateTimer;
|
QTimer *m_autoUpdateTimer;
|
||||||
bool m_globalAutoUpdateEnabled;
|
bool m_globalAutoUpdateEnabled;
|
||||||
int m_globalAutoUpdateInitialInterval;
|
int m_globalAutoUpdateInitialInterval;
|
||||||
int m_globalAutoUpdateRemainingInterval;
|
int m_globalAutoUpdateRemainingInterval;
|
||||||
|
|
||||||
|
ServiceOperator *m_serviceOperator;
|
||||||
|
|
||||||
QThread *m_feedDownloaderThread;
|
QThread *m_feedDownloaderThread;
|
||||||
FeedDownloader *m_feedDownloader;
|
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());
|
return DatabaseQueries::getUndeletedMessagesForAccount(database, accountId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServiceRoot::saveAllCachedData() {
|
||||||
|
}
|
||||||
|
|
||||||
void ServiceRoot::itemChanged(const QList<RootItem*> &items) {
|
void ServiceRoot::itemChanged(const QList<RootItem*> &items) {
|
||||||
emit dataChanged(items);
|
emit dataChanged(items);
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ class ServiceRoot : public RootItem {
|
|||||||
// NOTE: Caller does NOT take ownership of created menu!
|
// NOTE: Caller does NOT take ownership of created menu!
|
||||||
virtual QList<QAction*> addItemMenu();
|
virtual QList<QAction*> addItemMenu();
|
||||||
|
|
||||||
|
// Returns actions to display as context menu.
|
||||||
QList<QAction*> contextMenu();
|
QList<QAction*> contextMenu();
|
||||||
|
|
||||||
// Returns list of specific actions to be shown in main window menu
|
// 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 start(bool freshly_activated) = 0;
|
||||||
virtual void stop() = 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).
|
// Account ID corresponds with DB attribute Accounts (id).
|
||||||
int accountId() const;
|
int accountId() const;
|
||||||
void setAccountId(int account_id);
|
void setAccountId(int account_id);
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include "services/owncloud/gui/formeditowncloudaccount.h"
|
#include "services/owncloud/gui/formeditowncloudaccount.h"
|
||||||
#include "services/owncloud/gui/formowncloudfeeddetails.h"
|
#include "services/owncloud/gui/formowncloudfeeddetails.h"
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
|
||||||
OwnCloudServiceRoot::OwnCloudServiceRoot(RootItem *parent)
|
OwnCloudServiceRoot::OwnCloudServiceRoot(RootItem *parent)
|
||||||
: ServiceRoot(parent), m_recycleBin(new OwnCloudRecycleBin(this)),
|
: 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) {
|
void OwnCloudServiceRoot::addNewFeed(const QString &url) {
|
||||||
if (!qApp->feedUpdateLock()->tryLock()) {
|
if (!qApp->feedUpdateLock()->tryLock()) {
|
||||||
// Lock was not obtained because
|
// Lock was not obtained because
|
||||||
|
@ -51,6 +51,8 @@ class OwnCloudServiceRoot : public ServiceRoot {
|
|||||||
void updateTitle();
|
void updateTitle();
|
||||||
void saveAccountDataToDatabase();
|
void saveAccountDataToDatabase();
|
||||||
|
|
||||||
|
void saveAllCachedData();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addNewFeed(const QString &url);
|
void addNewFeed(const QString &url);
|
||||||
void addNewCategory();
|
void addNewCategory();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user