Skip to content

Commit

Permalink
[qmf] Introduce QMailAccount::HasPersistentConnection status flag
Browse files Browse the repository at this point in the history
Use QMailAccount::HasPersistentConnection status flag for IMAP idle instead of
updating last sync time every minute, this reduces accounts db writes(they
trigger notifications to other processes) and also make use of a linger
keepalive(less state transitions).
  • Loading branch information
Valerio Valerio committed Dec 6, 2014
1 parent bc4f45b commit d45bc6c
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 38 deletions.
11 changes: 11 additions & 0 deletions qmf/src/libraries/qmfclient/qmailaccount.cpp
Expand Up @@ -68,6 +68,7 @@ static quint64 canTransmitViaReferenceFlag = 0;
static quint64 canCreateFoldersFlag = 0;
static quint64 useSmartReplyFlag = 0;
static quint64 canSearchOnServerFlag = 0;
static quint64 hasPersistentConnectionFlag = 0;

class QMailAccountPrivate : public QSharedData
{
Expand Down Expand Up @@ -352,6 +353,15 @@ class QMailAccountPrivate : public QSharedData
\sa QMailSearchAction::searchMessages()
*/

/*!
\variable QMailAccount::HasPersistentConnection
The status mask needed for testing the value of the registered status flag named
\c "HasPersistentConnection" against the result of QMailAccount::status().
This flag indicates that an account has a persistent connection to the server(always online).
*/

const quint64 &QMailAccount::SynchronizationEnabled = synchronizationEnabledFlag;
const quint64 &QMailAccount::Synchronized = synchronizedFlag;
const quint64 &QMailAccount::AppendSignature = appendSignatureFlag;
Expand All @@ -368,6 +378,7 @@ const quint64 &QMailAccount::CanTransmitViaReference = canTransmitViaReferenceFl
const quint64 &QMailAccount::CanCreateFolders = canCreateFoldersFlag;
const quint64 &QMailAccount::UseSmartReply = useSmartReplyFlag;
const quint64 &QMailAccount::CanSearchOnServer = canSearchOnServerFlag;
const quint64 &QMailAccount::HasPersistentConnection = hasPersistentConnectionFlag;

/*!
Creates an uninitialised account object.
Expand Down
1 change: 1 addition & 0 deletions qmf/src/libraries/qmfclient/qmailaccount.h
Expand Up @@ -84,6 +84,7 @@ class QMF_EXPORT QMailAccount
static const quint64 &CanCreateFolders;
static const quint64 &UseSmartReply;
static const quint64 &CanSearchOnServer;
static const quint64 &HasPersistentConnection;

QMailAccount();
explicit QMailAccount(const QMailAccountId& id);
Expand Down
11 changes: 11 additions & 0 deletions qmf/src/libraries/qmfclient/qmailstore_p.cpp
Expand Up @@ -2672,6 +2672,10 @@ bool SSOAccountSatisfyTheProperty(Accounts::Account* ssoAccount, const QMailAcco
status &= (~QMailAccount::AppendSignature);
status |= appendSignature?(QMailAccount::AppendSignature):0;

bool hasPersistentConnection = ssoAccount->valueAsBool("hasPersistentConnection", false);
status &= (~QMailAccount::HasPersistentConnection);
status |= hasPersistentConnection?(QMailAccount::HasPersistentConnection):0;

return SSOAccountCompareProperty<quint64>(ssoAccount,
status,
argument.op, argument.valueList);
Expand Down Expand Up @@ -3107,6 +3111,7 @@ bool QMailStorePrivate::initStore()
|| attemptRegisterStatusBit("CanCreateFolders", "accountstatus", 63, true, const_cast<quint64 *>(&QMailAccount::CanCreateFolders), t, false)
|| attemptRegisterStatusBit("UseSmartReply", "accountstatus", 63, true, const_cast<quint64 *>(&QMailAccount::UseSmartReply), t, false)
|| attemptRegisterStatusBit("CanSearchOnServer", "accountstatus", 63, true, const_cast<quint64 *>(&QMailAccount::CanSearchOnServer), t, false)
|| attemptRegisterStatusBit("HasPersistentConnection", "accountstatus", 63, true, const_cast<quint64 *>(&QMailAccount::HasPersistentConnection), t, false)
|| attemptRegisterStatusBit("SynchronizationEnabled", "folderstatus", 63, true, const_cast<quint64 *>(&QMailFolder::SynchronizationEnabled), t, false)
|| attemptRegisterStatusBit("Synchronized", "folderstatus", 63, true, const_cast<quint64 *>(&QMailFolder::Synchronized), t, false)
|| attemptRegisterStatusBit("PartialContent", "folderstatus", 63, true, const_cast<quint64 *>(&QMailFolder::PartialContent), t, false)
Expand Down Expand Up @@ -3642,11 +3647,13 @@ QMailAccount QMailStorePrivate::extractAccount(const QSharedPointer<Accounts::Ac
const bool& isDefault = ssoAccount->valueAsBool("email/default");
const bool& canTransmit = ssoAccount->valueAsBool("canTransmit", true);
const bool& appendSignature = ssoAccount->valueAsBool("signatureEnabled", true);
const bool& hasPersistentConnection = ssoAccount->valueAsBool("hasPersistentConnection", false);

result.setStatus(QMailAccount::Enabled, enabled);
result.setStatus(QMailAccount::PreferredSender, isDefault);
result.setStatus(QMailAccount::CanTransmit, canTransmit);
result.setStatus(QMailAccount::AppendSignature, appendSignature);
result.setStatus(QMailAccount::HasPersistentConnection, hasPersistentConnection);

result.setSignature(ssoAccount->valueAsString("signature"));
result.setFromAddress(ssoAccount->contains("fullName")?
Expand Down Expand Up @@ -6148,6 +6155,8 @@ QMailStorePrivate::AttemptResult QMailStorePrivate::attemptAddAccount(QMailAccou
ssoAccount->setValue("status", account->status());
const bool appendSignature = (account->status() & QMailAccount::AppendSignature);
ssoAccount->setValue("signatureEnabled", appendSignature);
const bool hasPersistentConnection = (account->status() & QMailAccount::HasPersistentConnection);
ssoAccount->setValue("hasPersistentConnection", hasPersistentConnection);
ssoAccount->setValue("signature", account->signature());
ssoAccount->setValue("emailaddress", account->fromAddress().address());
ssoAccount->setValue("fullName", account->fromAddress().name());
Expand Down Expand Up @@ -6950,6 +6959,8 @@ QMailStorePrivate::AttemptResult QMailStorePrivate::attemptUpdateAccount(QMailAc
ssoAccount->setValue("status", account->status());
bool signatureEnabled = account->status() & QMailAccount::AppendSignature;
ssoAccount->setValue("signatureEnabled", signatureEnabled);
bool hasPersistentConnection = account->status() & QMailAccount::HasPersistentConnection;
ssoAccount->setValue("hasPersistentConnection", hasPersistentConnection);
ssoAccount->setValue("signature", account->signature());
ssoAccount->setValue("emailaddress", account->fromAddress().address());
ssoAccount->setValue("fullName", account->fromAddress().name());
Expand Down
13 changes: 12 additions & 1 deletion qmf/src/plugins/messageservices/imap/imapclient.cpp
Expand Up @@ -1668,7 +1668,18 @@ void ImapClient::setAccount(const QMailAccountId &id)
}

_config = QMailAccountConfiguration(id);

// At this point account can't have a persistent connection to the server, if for some reason the status is wrong(crash/abort) we will
// reset correct status here.
QMailAccount account(id);
const bool hasPersistentConnection = (account.status() & QMailAccount::HasPersistentConnection);
if (hasPersistentConnection) {
account.setStatus(QMailAccount::HasPersistentConnection, false);
if (!QMailStore::instance()->updateAccount(&account)) {
qWarning() << "Unable to update account" << account.id() << "to HasPersistentConnection" << false;
} else {
qMailLog(Messaging) << "HasPersistentConnection for " << account.id() << "changed to" << false;
}
}
#ifdef USE_ACCOUNTS_QT
if (!_ssoSessionManager) {
ImapConfiguration imapCfg(_config);
Expand Down
68 changes: 34 additions & 34 deletions qmf/src/plugins/messageservices/imap/imapservice.cpp
Expand Up @@ -1508,11 +1508,8 @@ ImapService::ImapService(const QMailAccountId &accountId)
_initiatePushEmailTimer(new QTimer(this))
{
#ifdef USE_KEEPALIVE
_lastSyncCounter = 0;
_idling = false;
_backgroundActivity = new BackgroundActivity(this);
_backgroundActivity->setWakeupFrequency(BackgroundActivity::ThirtySeconds);
connect(_backgroundActivity, SIGNAL(running()), this, SLOT(onUpdateLastSyncTime()));
#endif

QMailAccount account(accountId);
Expand Down Expand Up @@ -1581,14 +1578,23 @@ void ImapService::disable()
{
QMailAccountConfiguration accountCfg(_accountId);
ImapConfiguration imapCfg(accountCfg);
QMailAccount account(_accountId);
const bool hasPersistentConnection = (account.status() & QMailAccount::HasPersistentConnection);
if (hasPersistentConnection) {
account.setStatus(QMailAccount::HasPersistentConnection, false);
if (!QMailStore::instance()->updateAccount(&account)) {
qWarning() << "Unable to update account" << account.id() << "to HasPersistentConnection" << false;
} else {
qMailLog(Messaging) << "HasPersistentConnection for " << account.id() << "changed to" << false;
}
}
_accountWasEnabled = false;
_accountWasPushEnabled = imapCfg.pushEnabled();
_previousPushFolders = imapCfg.pushFolders();
_previousConnectionSettings = connectionSettings(imapCfg);
_restartPushEmailTimer->stop();
_initiatePushEmailTimer->stop();
#ifdef USE_KEEPALIVE
_idling = false;
_backgroundActivity->stop();
#endif
_source->setIntervalTimer(0);
Expand Down Expand Up @@ -1704,7 +1710,6 @@ void ImapService::initiatePushEmail()
_restartPushEmailTimer->stop();
_initiatePushEmailTimer->stop();
#ifdef USE_KEEPALIVE
_idling = false;
if (_backgroundActivity->isRunning()) {
_backgroundActivity->stop();
qMailLog(Messaging) << Q_FUNC_INFO << "Stopping keepalive";
Expand All @@ -1714,11 +1719,20 @@ void ImapService::initiatePushEmail()
if (ids.count()) {
_establishingPushEmail = true;
#ifdef USE_KEEPALIVE
qMailLog(Messaging) << Q_FUNC_INFO << "Starting keepalive";
_lastSyncCounter = 0;
_idling = true;
_backgroundActivity->wait();
qMailLog(Messaging) << Q_FUNC_INFO << "Starting keepalive";
_backgroundActivity->run();
#endif
QMailAccount account(_accountId);
const bool hasPersistentConnection = (account.status() & QMailAccount::HasPersistentConnection);
if (!hasPersistentConnection) {
account.setStatus(QMailAccount::HasPersistentConnection, true);
if (!QMailStore::instance()->updateAccount(&account)) {
qWarning() << "Unable to update account" << account.id() << "to HasPersistentConnection" << true;
} else {
qMailLog(Messaging) << "HasPersistentConnection for " << account.id() << "changed to" << true;
}
}

foreach(QMailFolderId id, ids) {
// Check for flag changes and new mail
_source->queueFlagsChangedCheck(id);
Expand Down Expand Up @@ -1767,35 +1781,21 @@ void ImapService::updateStatus(const QString &text)
}

#ifdef USE_KEEPALIVE
void ImapService::onUpdateLastSyncTime()
{
if (_idling && _client->idlesEstablished()) {
_lastSyncCounter++;
if (_lastSyncCounter == 2) {
QMailAccount account(_accountId);
account.setLastSynchronized(QMailTimeStamp::currentDateTime());
if (!QMailStore::instance()->updateAccount(&account)) {
qWarning() << "Unable to update account" << account.id() << "to set lastSynchronized";
}
_lastSyncCounter = 0;
}
}

// start timer again if still in idle mode
if (_idling) {
_backgroundActivity->wait();
} else if (_backgroundActivity->isRunning()){
qMailLog(Messaging) << Q_FUNC_INFO << "Stopping keepalive";
_backgroundActivity->stop();
_lastSyncCounter = 0;
}
}

void ImapService::stopPushEmail()
{
qMailLog(Messaging) << "Stopping push email for account" << _accountId
<< QMailAccount(_accountId).name();
_idling = false;

QMailAccount account(_accountId);
const bool hasPersistentConnection = (account.status() & QMailAccount::HasPersistentConnection);
if (hasPersistentConnection) {
account.setStatus(QMailAccount::HasPersistentConnection, false);
if (!QMailStore::instance()->updateAccount(&account)) {
qWarning() << "Unable to update account" << account.id() << "to HasPersistentConnection" << false;
} else {
qMailLog(Messaging) << "HasPersistentConnection for " << account.id() << "changed to" << false;
}
}
_backgroundActivity->stop();
_restartPushEmailTimer->stop();
_initiatePushEmailTimer->stop();
Expand Down
3 changes: 0 additions & 3 deletions qmf/src/plugins/messageservices/imap/imapservice.h
Expand Up @@ -79,7 +79,6 @@ protected slots:
void updateStatus(const QString& text);

#ifdef USE_KEEPALIVE
void onUpdateLastSyncTime();
void stopPushEmail();
#endif

Expand All @@ -102,8 +101,6 @@ protected slots:
QTimer *_initiatePushEmailTimer;
#ifdef USE_KEEPALIVE
BackgroundActivity* _backgroundActivity;
int _lastSyncCounter;
bool _idling;
#endif
};

Expand Down

0 comments on commit d45bc6c

Please sign in to comment.