Use connection validator to ping the server. #2485

* Stop the quota job from having an effect on account status
  as it can sometimes take a long time to reply. See #2485 and
  owncloud/core#12744.

* Instead of indirectly using the quota job, use the connection
  validator to regularly ping the server with a basic PROPFIND for
  'getlastmodified' on /.
  This request was usually fast for users even when the quota PROPFIND
  was slow.
This commit is contained in:
Christian Kamm 2014-12-03 13:10:49 +01:00
parent 8dff17d78b
commit d8c59fcb73
7 changed files with 50 additions and 44 deletions

View file

@ -275,18 +275,27 @@ void Application::slotToggleFolderman(int state)
FolderMan* folderMan = FolderMan::instance();
switch (state) {
case Account::Connected:
qDebug() << "Enabling sync scheduler, scheduling all folders";
folderMan->setSyncEnabled(true);
folderMan->slotScheduleAllFolders();
break;
case Account::Disconnected:
_checkConnectionTimer.start();
// fall through
case Account::SignedOut:
case Account::InvalidCredential:
case Account::Disconnected:
qDebug() << "Disabling sync scheduler, terminating sync";
folderMan->setSyncEnabled(false);
folderMan->terminateSyncProcess();
break;
}
// Stop checking the connection if we're manually signed out or
// when the credentials are wrong.
if (state == Account::SignedOut
|| state == Account::InvalidCredential) {
_checkConnectionTimer.stop();
} else if (! _checkConnectionTimer.isActive()) {
_checkConnectionTimer.start();
}
}
void Application::slotCrash()
@ -299,24 +308,14 @@ void Application::slotConnectionValidatorResult(ConnectionValidator::Status stat
qDebug() << "Connection Validator Result: " << _conValidator->statusString(status);
QStringList startupFails;
if( status == ConnectionValidator::Connected ) {
FolderMan *folderMan = FolderMan::instance();
qDebug() << "######## Connection and Credentials are ok!";
folderMan->setSyncEnabled(true);
// queue up the sync for all folders.
folderMan->slotScheduleAllFolders();
_checkConnectionTimer.stop();
} else {
// if we have problems here, it's unlikely that syncing will work.
FolderMan::instance()->setSyncEnabled(false);
if( status != ConnectionValidator::Connected ) {
startupFails = _conValidator->errors();
_startupNetworkError = _conValidator->networkError();
if (_userTriggeredConnect) {
_userTriggeredConnect = false;
}
}
_gui->startupConnected( (status == ConnectionValidator::Connected), startupFails);
_gui->setConnectionErrors( (status == ConnectionValidator::Connected), startupFails);
_conValidator->deleteLater();
}

View file

@ -201,17 +201,8 @@ void ownCloudGui::slotAccountStateChanged()
slotComputeOverallSyncStatus();
}
void ownCloudGui::startupConnected( bool connected, const QStringList& fails )
void ownCloudGui::setConnectionErrors( bool /*connected*/, const QStringList& fails )
{
FolderMan *folderMan = FolderMan::instance();
if( connected ) {
qDebug() << "######## connected to ownCloud Server!";
folderMan->setSyncEnabled(true);
// _tray->setIcon( Theme::instance()->syncStateIcon( SyncResult::NotYetStarted, true ) );
// _tray->show();
}
_startupFails = fails; // store that for the settings dialog once it appears.
if( !_settingsDialog.isNull() ) {
_settingsDialog->setGeneralErrors( _startupFails );

View file

@ -39,7 +39,7 @@ public:
explicit ownCloudGui(Application *parent = 0);
void setupContextMenu();
void startupConnected(bool connected , const QStringList &fails);
void setConnectionErrors(bool connected , const QStringList &fails);
bool checkAccountExists(bool openSettings);

View file

@ -373,11 +373,29 @@ int Account::state() const
void Account::setState(int state)
{
if (_state != state) {
qDebug() << "Account state change: "
<< stateString(_state) << "->" << stateString(state);
_state = state;
emit stateChanged(state);
}
}
QString Account::stateString(int state)
{
switch (state)
{
case Connected:
return QLatin1String("Connected");
case Disconnected:
return QLatin1String("Disconnected");
case SignedOut:
return QLatin1String("SignedOut");
case InvalidCredential:
return QLatin1String("InvalidCredential");
}
return QLatin1String("Unknown");
}
QuotaInfo *Account::quotaInfo()
{
return _quotaInfo;

View file

@ -148,6 +148,7 @@ public:
int state() const;
void setState(int state);
static QString stateString(int state);
void clearCookieJar();

View file

@ -80,16 +80,23 @@ QString ConnectionValidator::statusString( Status stat ) const
void ConnectionValidator::checkConnection()
{
if( _account ) {
if( !_account ) {
_errors << tr("No ownCloud account configured");
emit connectionResult( NotConfigured );
return;
}
if( _account->state() == Account::Connected ) {
// When we're already connected, just make sure a minimal request
// gets replied to.
slotCheckAuthentication();
} else {
CheckServerJob *checkJob = new CheckServerJob(_account, false, this);
checkJob->setIgnoreCredentialFailure(true);
connect(checkJob, SIGNAL(instanceFound(QUrl,QVariantMap)), SLOT(slotStatusFound(QUrl,QVariantMap)));
connect(checkJob, SIGNAL(networkError(QNetworkReply*)), SLOT(slotNoStatusFound(QNetworkReply*)));
connect(checkJob, SIGNAL(timeout(QUrl)), SLOT(slotStatusTimeout(QUrl)));
checkJob->start();
} else {
_errors << tr("No ownCloud account configured");
emit connectionResult( NotConfigured );
}
}
@ -100,7 +107,6 @@ void ConnectionValidator::slotStatusFound(const QUrl&url, const QVariantMap &inf
<< url << " with version "
<< CheckServerJob::versionString(info)
<< "(" << CheckServerJob::version(info) << ")";
// now check the authentication
if( CheckServerJob::version(info).startsWith("4.0") ) {
_errors.append( tr("The configured server for this client is too old") );
@ -109,6 +115,7 @@ void ConnectionValidator::slotStatusFound(const QUrl&url, const QVariantMap &inf
return;
}
// now check the authentication
AbstractCredentials *creds = _account->credentials();
if (creds->ready()) {
QTimer::singleShot( 0, this, SLOT( slotCheckAuthentication() ));
@ -146,14 +153,15 @@ void ConnectionValidator::slotCheckAuthentication()
AbstractCredentials *creds = _account->credentials();
disconnect( creds, SIGNAL(fetched()),
this, SLOT(slotCheckAuthentication()));
// simply GET the webdav root, will fail if credentials are wrong.
// continue in slotAuthCheck here :-)
qDebug() << "# Check whether authenticated propfind works.";
PropfindJob *job = new PropfindJob(_account, "/", this);
job->setProperties(QList<QByteArray>() << "getlastmodified");
connect(job, SIGNAL(result(QVariantMap)), SLOT(slotAuthSuccess()));
connect(job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotAuthFailed(QNetworkReply*)));
job->start();
qDebug() << "# checking for authentication settings.";
}
void ConnectionValidator::slotAuthFailed(QNetworkReply *reply)
@ -166,11 +174,7 @@ void ConnectionValidator::slotAuthFailed(QNetworkReply *reply)
qDebug() << "******** Password is wrong!";
_errors << tr("The provided credentials are not correct");
stat = CredentialsWrong;
switch (_account->state()) {
case Account::SignedOut:
_account->setState(Account::SignedOut);
break;
default:
if (_account->state() != Account::SignedOut) {
_account->setState(Account::Disconnected);
}

View file

@ -62,10 +62,6 @@ void QuotaInfo::slotAccountStateChanged(int state)
void QuotaInfo::slotRequestFailed()
{
if (!_account.isNull() && _account->state() == Account::Connected) {
_account->setState(Account::Disconnected);
}
_lastQuotaTotalBytes = 0;
_lastQuotaUsedBytes = 0;
_jobRestartTimer->start(failIntervalT);
@ -84,9 +80,6 @@ void QuotaInfo::slotCheckQuota()
void QuotaInfo::slotUpdateLastQuota(qint64 total, qint64 used)
{
if(_account->state() == Account::Disconnected) {
_account->setState(Account::Connected);
}
_lastQuotaTotalBytes = total;
_lastQuotaUsedBytes = used;
emit quotaUpdated(total, used);