Commit a2ada719 authored by Daniel Vrátil's avatar Daniel Vrátil 🤖
Browse files

Send dummy queries to MySQL to keep the connection alive

MySQL server will drop connection when there's no query for longer
period of time. The timeout does not seem to be configurable and
QSqlDatabase is unable to detect that the connection has been dropped
and isValid() and isOpen() will still return true.

To work around this problem, we send a dummy SQL query to MySQL
every hour. It has been confirmed by long-term testing that
this is enough.
parent d76aeb18
......@@ -44,6 +44,7 @@
#include <QtCore/QStringList>
#include <QtCore/QThread>
#include <QtCore/QThreadStorage>
#include <QtCore/QTimer>
#include <QtCore/QUuid>
#include <QtCore/QVariant>
#include <QtSql/QSqlDatabase>
......@@ -67,12 +68,24 @@ DataStore::DataStore() :
QObject(),
m_dbOpened( false ),
m_transactionLevel( 0 ),
mNotificationCollector( new NotificationCollector( this ) )
mNotificationCollector( new NotificationCollector( this ) ),
m_keepAliveTimer( 0 )
{
open();
m_transactionLevel = 0;
NotificationManager::self()->connectNotificationCollector( mNotificationCollector );
if ( DbConfig::configuredDatabase()->driverName() == QLatin1String( "QMYSQL" ) ) {
// Send a dummy query to MySQL every 1 hour to keep the connection alive,
// otherwise MySQL just drops the connection and our subsequent queries fail
// without properly reporting the error
m_keepAliveTimer = new QTimer( this );
m_keepAliveTimer->setInterval( 3600 * 1000 );
QObject::connect( m_keepAliveTimer, SIGNAL(timeout()),
this, SLOT(sendKeepAliveQuery()) );
m_keepAliveTimer->start();
}
}
DataStore::~DataStore()
......@@ -119,6 +132,7 @@ void Akonadi::DataStore::close()
QSqlDatabase::removeDatabase( m_connectionName );
m_dbOpened = false;
m_keepAliveTimer->stop();
}
bool Akonadi::DataStore::init()
......@@ -916,3 +930,10 @@ bool Akonadi::DataStore::inTransaction() const
return m_transactionLevel > 0;
}
void DataStore::sendKeepAliveQuery()
{
if ( m_database.isOpen() ) {
QSqlQuery query( m_database );
query.exec( QLatin1String( "SELECT 1" ) );
}
}
......@@ -28,6 +28,7 @@
#include <QtSql/QSqlDatabase>
class QSqlQuery;
class QTimer;
#include "entities.h"
#include "notificationcollector.h"
......@@ -280,6 +281,9 @@ protected:
*/
static QDateTime dateTimeToQDateTime( const QByteArray & dateTime );
private Q_SLOTS:
void sendKeepAliveQuery();
private:
QString m_connectionName;
QSqlDatabase m_database;
......@@ -287,6 +291,7 @@ private:
uint m_transactionLevel;
QByteArray mSessionId;
NotificationCollector* mNotificationCollector;
QTimer *m_keepAliveTimer;
static bool s_hasForeignKeyConstraints;
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment