Merge pull request #3378 from owncloud/quota-only-when-ui-visible

QuotaInfo: only request the quota when the UI is visible
This commit is contained in:
Olivier Goffart 2015-06-29 10:56:52 +02:00
commit 389faa4bcb
6 changed files with 80 additions and 46 deletions

View file

@ -62,7 +62,8 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent) :
QWidget(parent),
ui(new Ui::AccountSettings),
_wasDisabledBefore(false),
_accountState(accountState)
_accountState(accountState),
_quotaInfo(accountState)
{
ui->setupUi(this);
@ -123,10 +124,8 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent) :
connect(_accountState, SIGNAL(stateChanged(int)), SLOT(slotAccountStateChanged(int)));
slotAccountStateChanged(_accountState->state());
QuotaInfo *quotaInfo = _accountState->quotaInfo();
connect( quotaInfo, SIGNAL(quotaUpdated(qint64,qint64)),
connect( &_quotaInfo, SIGNAL(quotaUpdated(qint64,qint64)),
this, SLOT(slotUpdateQuota(qint64,qint64)));
slotUpdateQuota(quotaInfo->lastQuotaTotalBytes(), quotaInfo->lastQuotaUsedBytes());
connect(ui->deleteButton, SIGNAL(clicked()) , this, SLOT(slotDeleteAccount()));
@ -514,5 +513,12 @@ void AccountSettings::slotDeleteAccount()
manager->save();
}
bool AccountSettings::event(QEvent* e)
{
if (e->type() == QEvent::Hide || e->type() == QEvent::Show) {
_quotaInfo.setActive(isVisible());
}
return QWidget::event(e);
}
} // namespace OCC

View file

@ -21,6 +21,7 @@
#include <QTimer>
#include "folder.h"
#include "quotainfo.h"
#include "progressdispatcher.h"
class QModelIndex;
@ -76,9 +77,11 @@ protected slots:
void slotDeleteAccount();
void refreshSelectiveSyncStatus();
void slotForceRemoteDiscoveryOnFolders();
void slotCustomContextMenuRequested(const QPoint&);
private:
void showConnectionLabel( const QString& message, const QString& tooltip = QString() );
bool event(QEvent*) Q_DECL_OVERRIDE;
Ui::AccountSettings *ui;
@ -88,8 +91,7 @@ private:
bool _wasDisabledBefore;
AccountState *_accountState;
QLabel *_quotaLabel;
private slots:
void slotCustomContextMenuRequested(const QPoint&);
QuotaInfo _quotaInfo;
};
} // namespace OCC

View file

@ -12,7 +12,6 @@
*/
#include "accountstate.h"
#include "quotainfo.h"
#include "accountmanager.h"
#include "account.h"
#include "creds/abstractcredentials.h"
@ -25,15 +24,12 @@ namespace OCC {
AccountState::AccountState(AccountPtr account)
: QObject()
, _account(account)
, _quotaInfo(0)
, _state(AccountState::Disconnected)
, _connectionStatus(ConnectionValidator::Undefined)
, _waitingForNewCredentials(false)
{
qRegisterMetaType<AccountState*>("AccountState*");
_quotaInfo = new QuotaInfo(this); // Need to be initialized when 'this' is fully initialized
connect(account.data(), SIGNAL(invalidCredentials()),
SLOT(slotInvalidCredentials()));
connect(account.data(), SIGNAL(credentialsFetched(AbstractCredentials*)),
@ -134,11 +130,6 @@ bool AccountState::isConnectedOrTemporarilyUnavailable() const
return isConnected() || _state == ServiceUnavailable;
}
QuotaInfo *AccountState::quotaInfo()
{
return _quotaInfo;
}
void AccountState::checkConnectivity()
{
if (isSignedOut() || _waitingForNewCredentials) {

View file

@ -25,7 +25,6 @@ class QSettings;
namespace OCC {
class QuotaInfo;
class AccountState;
class Account;
class AbstractCredentials;
@ -82,8 +81,6 @@ public:
bool isConnected() const;
bool isConnectedOrTemporarilyUnavailable() const;
QuotaInfo *quotaInfo();
/// Triggers a ping to the server to update state and
/// connection status and errors.
void checkConnectivity();
@ -106,7 +103,6 @@ protected Q_SLOTS:
private:
AccountPtr _account;
QuotaInfo *_quotaInfo;
State _state;
ConnectionStatus _connectionStatus;
QStringList _connectionErrors;

View file

@ -25,31 +25,39 @@ namespace OCC {
namespace {
static const int defaultIntervalT = 30*1000;
static const int failIntervalT = 5*1000;
static const int initialTimeT = 1*1000;
}
QuotaInfo::QuotaInfo(AccountState *accountState)
: QObject(accountState)
QuotaInfo::QuotaInfo(AccountState *accountState, QObject *parent)
: QObject(parent)
, _accountState(accountState)
, _lastQuotaTotalBytes(0)
, _lastQuotaUsedBytes(0)
, _jobRestartTimer(new QTimer(this))
, _active(false)
{
connect(accountState, SIGNAL(stateChanged(int)),
SLOT(slotAccountStateChanged(int)));
connect(_jobRestartTimer, SIGNAL(timeout()), SLOT(slotCheckQuota()));
_jobRestartTimer->setSingleShot(true);
if (canGetQuota()) {
_jobRestartTimer->start(initialTimeT);
}
SLOT(slotAccountStateChanged()));
connect(&_jobRestartTimer, SIGNAL(timeout()), SLOT(slotCheckQuota()));
_jobRestartTimer.setSingleShot(true);
}
void QuotaInfo::slotAccountStateChanged(int /*state*/)
void QuotaInfo::setActive(bool active)
{
_active = active;
slotAccountStateChanged();
}
void QuotaInfo::slotAccountStateChanged()
{
if (canGetQuota()) {
_jobRestartTimer->start(initialTimeT);
auto elapsed = _lastQuotaRecieved.msecsTo(QDateTime::currentDateTime());
if (_lastQuotaRecieved.isNull() || elapsed >= defaultIntervalT) {
slotCheckQuota();
} else {
_jobRestartTimer.start(defaultIntervalT - elapsed);
}
} else {
_jobRestartTimer->stop();
_jobRestartTimer.stop();
}
}
@ -57,12 +65,12 @@ void QuotaInfo::slotRequestFailed()
{
_lastQuotaTotalBytes = 0;
_lastQuotaUsedBytes = 0;
_jobRestartTimer->start(failIntervalT);
_jobRestartTimer.start(failIntervalT);
}
bool QuotaInfo::canGetQuota() const
{
if (! _accountState) {
if (! _accountState || !_active) {
return false;
}
AccountPtr account = _accountState->account();
@ -77,12 +85,17 @@ void QuotaInfo::slotCheckQuota()
return;
}
if (_job) {
// The previous job was not finished? Then we cancel it!
_job->deleteLater();
}
AccountPtr account = _accountState->account();
PropfindJob *job = new PropfindJob(account, "/", this);
job->setProperties(QList<QByteArray>() << "quota-available-bytes" << "quota-used-bytes");
connect(job, SIGNAL(result(QVariantMap)), SLOT(slotUpdateLastQuota(QVariantMap)));
connect(job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotRequestFailed()));
job->start();
_job = new PropfindJob(account, "/", this);
_job->setProperties(QList<QByteArray>() << "quota-available-bytes" << "quota-used-bytes");
connect(_job, SIGNAL(result(QVariantMap)), SLOT(slotUpdateLastQuota(QVariantMap)));
connect(_job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotRequestFailed()));
_job->start();
}
void QuotaInfo::slotUpdateLastQuota(const QVariantMap &result)
@ -93,7 +106,8 @@ void QuotaInfo::slotUpdateLastQuota(const QVariantMap &result)
_lastQuotaUsedBytes = result["quota-used-bytes"].toDouble();
_lastQuotaTotalBytes = _lastQuotaUsedBytes + avail;
emit quotaUpdated(_lastQuotaTotalBytes, _lastQuotaUsedBytes);
_jobRestartTimer->start(defaultIntervalT);
_jobRestartTimer.start(defaultIntervalT);
_lastQuotaRecieved = QDateTime::currentDateTime();
}
}

View file

@ -17,27 +17,49 @@
#include <QObject>
#include <QPointer>
#include <QVariant>
class QTimer;
#include <QTimer>
#include <QDateTime>
namespace OCC {
class AccountState;
class PropfindJob;
/**
* This class handle the getting the quota to display in the UI
* It is typically owned by the AccountSetting page.
*
* The quota is requested if those 3 conditions are met:
* - This object is active via setActive() (typically if the settings page is visible.)
* - The account is connected.
* - Every 30 seconds (defaultIntervalT) or 5 seconds in case of failure (failIntervalT)
*
* We only request the quota when the UI is visible otherwise this might slow down the server with
* too many requests. But we still need to do it every 30 seconds otherwise user complains that the
* quota is not updated fast enough when changed on the server.
*
* If the quota job is not finished within 30 seconds, it is cancelled and another one is started
*/
class QuotaInfo : public QObject {
Q_OBJECT
public:
QuotaInfo(AccountState *account);
explicit QuotaInfo(OCC::AccountState* accountState, QObject* parent = 0);
qint64 lastQuotaTotalBytes() const { return _lastQuotaTotalBytes; }
qint64 lastQuotaUsedBytes() const { return _lastQuotaUsedBytes; }
/**
* When the quotainfo is active, it requests the quota at regular interval.
* When setting it to active it will request the quota imediatly if the last time
* the quota was requested was more than the interval
*/
void setActive(bool active);
public Q_SLOTS:
void slotCheckQuota();
private Q_SLOTS:
void slotUpdateLastQuota(const QVariantMap &);
void slotAccountStateChanged(int state);
void slotAccountStateChanged();
void slotRequestFailed();
Q_SIGNALS:
@ -49,7 +71,10 @@ private:
QPointer<AccountState> _accountState;
qint64 _lastQuotaTotalBytes;
qint64 _lastQuotaUsedBytes;
QTimer *_jobRestartTimer;
QTimer _jobRestartTimer;
QDateTime _lastQuotaRecieved; // the time at which de quota was recieved last
bool _active; // if we should check at regular interval (when the UI is visible)
QPointer<PropfindJob> _job; // the currently running job
};