diff options
Diffstat (limited to 'src/Maintenance')
| -rw-r--r-- | src/Maintenance/maintenance.cpp | 7 | ||||
| -rw-r--r-- | src/Maintenance/maintenance.h | 33 | ||||
| -rw-r--r-- | src/Maintenance/onmaintenancetimeraction.cpp | 28 | ||||
| -rw-r--r-- | src/Maintenance/prunebeacons.cpp | 16 | ||||
| -rw-r--r-- | src/Maintenance/pruneplayers.cpp | 18 | ||||
| -rw-r--r-- | src/Maintenance/pruneserverinfo.cpp | 15 | ||||
| -rw-r--r-- | src/Maintenance/schedulemaintenance.cpp | 16 | ||||
| -rw-r--r-- | src/Maintenance/updatestats.cpp | 59 |
8 files changed, 192 insertions, 0 deletions
diff --git a/src/Maintenance/maintenance.cpp b/src/Maintenance/maintenance.cpp new file mode 100644 index 0000000..8869f99 --- /dev/null +++ b/src/Maintenance/maintenance.cpp @@ -0,0 +1,7 @@ +#include "maintenance.h" + +Maintenance::Maintenance(const QSharedPointer<CoreObject> &coreObject) +{ + // create local access + this->_coreObject = coreObject; +} diff --git a/src/Maintenance/maintenance.h b/src/Maintenance/maintenance.h new file mode 100644 index 0000000..b7a63a2 --- /dev/null +++ b/src/Maintenance/maintenance.h @@ -0,0 +1,33 @@ +#ifndef MAINTENANCE_H +#define MAINTENANCE_H + +#include <QTimer> + +#include "Core/CoreObject/coreobject.h" +#include "Database/databaseinterface.h" + +class Maintenance: public QObject +{ + Q_OBJECT + +public: + Maintenance(const QSharedPointer<CoreObject> &coreObject); + bool scheduleMaintenance(); + +private: + QSharedPointer<CoreObject> _coreObject; + + // schedule timer + QTimer _maintenanceTimer; + +private: + int updateStats(); + int pruneBeacons(); + int pruneServerInfo(); + int prunePlayers(); + +private slots: + void onMaintenanceTimerAction(); +}; + +#endif // MAINTENANCE_H diff --git a/src/Maintenance/onmaintenancetimeraction.cpp b/src/Maintenance/onmaintenancetimeraction.cpp new file mode 100644 index 0000000..97e5c51 --- /dev/null +++ b/src/Maintenance/onmaintenancetimeraction.cpp @@ -0,0 +1,28 @@ +#include "maintenance.h" + +// perform maintenance actions +void Maintenance::onMaintenanceTimerAction() +{ + // announce + _coreObject->Log.logEvent("main", QStringLiteral("performing maintenance")); + + // update statistics + int numUpdated = updateStats(); + if (numUpdated > 0) + _coreObject->Log.logEvent("stat", QStringLiteral("updated %1 game stats").arg(QString::number(numUpdated))); + + // prune direct beacons + int numPrunedBeacons = pruneBeacons(); + if (numPrunedBeacons > 0) + _coreObject->Log.logEvent("prune", QStringLiteral("pruned %1 direct beacons").arg(QString::number(numPrunedBeacons))); + + // prune serverinfo, serverinfo from which the serverlist entry is gone already + int numPrunedInfo = pruneServerInfo(); + if (numPrunedInfo > 0) + _coreObject->Log.logEvent("prune", QStringLiteral("pruned %1 server info entries").arg(QString::number(numPrunedInfo))); + + // prune orphaned players from which the serverinfo entry is gone already OR updateinfo is outdated + int numPrunedPlayers = prunePlayers(); + if (numPrunedPlayers > 0) + _coreObject->Log.logEvent("prune", QStringLiteral("pruned %1 players").arg(QString::number(numPrunedPlayers))); +} diff --git a/src/Maintenance/prunebeacons.cpp b/src/Maintenance/prunebeacons.cpp new file mode 100644 index 0000000..10e4630 --- /dev/null +++ b/src/Maintenance/prunebeacons.cpp @@ -0,0 +1,16 @@ +#include "maintenance.h" + +int Maintenance::pruneBeacons() +{ + QString updateString = "UPDATE serverlist " + "SET f_direct = 0 " + "WHERE f_direct = 1 AND dt_beacon < :timestamp"; + QSqlQuery updateQuery; + updateQuery.prepare(updateString); + updateQuery.bindValue(":timestamp", QDateTime::currentDateTime().addSecs(-600).toSecsSinceEpoch()); + + if ( ! updateQuery.exec() ) + return reportQuery(updateQuery); + + return updateQuery.numRowsAffected(); +} diff --git a/src/Maintenance/pruneplayers.cpp b/src/Maintenance/pruneplayers.cpp new file mode 100644 index 0000000..0bae4f9 --- /dev/null +++ b/src/Maintenance/pruneplayers.cpp @@ -0,0 +1,18 @@ +#include "maintenance.h" + +int Maintenance::prunePlayers() +{ + QString deleteString = "DELETE FROM playerinfo " + "WHERE playerinfo.sid NOT IN ( " + "SELECT serverinfo.sid FROM serverinfo) " + "OR dt_player < :timestamp"; + QSqlQuery deleteQuery; + deleteQuery.prepare(deleteString); + deleteQuery.bindValue(":timestamp", QDateTime::currentDateTime() + .addSecs(-7200).toSecsSinceEpoch()); // 2 hours + + if ( ! deleteQuery.exec() ) + return reportQuery(deleteQuery); + + return deleteQuery.numRowsAffected(); +} diff --git a/src/Maintenance/pruneserverinfo.cpp b/src/Maintenance/pruneserverinfo.cpp new file mode 100644 index 0000000..e3f2bd8 --- /dev/null +++ b/src/Maintenance/pruneserverinfo.cpp @@ -0,0 +1,15 @@ +#include "maintenance.h" + +int Maintenance::pruneServerInfo() +{ + QString deleteString = "DELETE FROM serverinfo " + "WHERE sid NOT IN ( " + "SELECT id FROM serverlist)"; + QSqlQuery deleteQuery; + deleteQuery.prepare(deleteString); + + if ( ! deleteQuery.exec() ) + return reportQuery(deleteQuery); + + return deleteQuery.numRowsAffected(); +} diff --git a/src/Maintenance/schedulemaintenance.cpp b/src/Maintenance/schedulemaintenance.cpp new file mode 100644 index 0000000..3a2decd --- /dev/null +++ b/src/Maintenance/schedulemaintenance.cpp @@ -0,0 +1,16 @@ +#include "maintenance.h" + +bool Maintenance::scheduleMaintenance() +{ + // set update timer + connect(&_maintenanceTimer, &QTimer::timeout, this, &Maintenance::onMaintenanceTimerAction); + + _maintenanceTimer.setInterval( _coreObject->Settings.MaintenanceSettings.timeMaintenanceInterval_s * 1000); + _maintenanceTimer.start(); + + // complete startup + _coreObject->Log.logEvent("info", QStringLiteral("performing maintenance every %1 seconds") + .arg(_coreObject->Settings.MaintenanceSettings.timeMaintenanceInterval_s)); + + return true; +} diff --git a/src/Maintenance/updatestats.cpp b/src/Maintenance/updatestats.cpp new file mode 100644 index 0000000..a19e7d9 --- /dev/null +++ b/src/Maintenance/updatestats.cpp @@ -0,0 +1,59 @@ +#include "maintenance.h" + +int Maintenance::updateStats() +{ + // result + int numOfUpdatedStats = 0; + + // get list of gamenames in database + QString selectGamenames = "SELECT DISTINCT gamename FROM serverlist"; + QSqlQuery gamenameQuery; + gamenameQuery.prepare(selectGamenames); + if ( ! gamenameQuery.exec() ) + return reportQuery(gamenameQuery); + + // update stats for every gamename + while ( gamenameQuery.next() ) + { + // get next gamename + QString gamename = gamenameQuery.value(0).toString(); + + // determine beacon and server counts + QString selectStats = "SELECT COUNT(CASE WHEN f_direct THEN 1 END) AS num_direct, " + "count(*) AS num_total " + "FROM serverlist " + "WHERE gamename = :gamename AND dt_updated > :timestamp"; + QSqlQuery statQuery; + statQuery.prepare(selectStats); + statQuery.bindValue(":gamename", gamename); + statQuery.bindValue(":timestamp", QDateTime::currentDateTime() + .addSecs(-_coreObject->Settings.ListenServerSettings.serverttl_s).toSecsSinceEpoch()); + if ( ! statQuery.exec() ) + return reportQuery(statQuery); + + // get values + int num_direct = -1; + int num_total = -1; + if ( statQuery.next() ) + { + num_direct = statQuery.value("num_direct").toInt(); + num_total = statQuery.value("num_total").toInt(); + } + + // write to db + QString updateStatQuery = "UPDATE gameinfo " + "SET num_direct = :num_direct, num_total = :num_total " + "WHERE gamename = :gamename "; + statQuery.prepare(updateStatQuery); + statQuery.bindValue(":num_direct", num_direct); + statQuery.bindValue(":num_total", num_total); + statQuery.bindValue(":gamename", gamename); + if ( ! statQuery.exec() ) + return reportQuery(statQuery); + + // update counter + numOfUpdatedStats += statQuery.numRowsAffected(); + } + + return numOfUpdatedStats; +} |
