diff --git a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java index fa9352356..46e589aa5 100644 --- a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java @@ -24,6 +24,7 @@ import com.gmail.nossr50.datatypes.player.PlayerProfile; import com.gmail.nossr50.datatypes.skills.AbilityType; import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.runnables.database.SQLReconnectTask; +import com.gmail.nossr50.runnables.database.SQLDatabaseKeepaliveTask; import com.gmail.nossr50.util.Misc; public final class SQLDatabaseManager implements DatabaseManager { @@ -51,6 +52,8 @@ public final class SQLDatabaseManager implements DatabaseManager { protected SQLDatabaseManager() { checkStructure(); + + new SQLDatabaseKeepaliveTask(this).runTaskTimerAsynchronously(mcMMO.p, 10, 60L * 60 * Misc.TICK_CONVERSION_FACTOR); } public void purgePowerlessUsers() { diff --git a/src/main/java/com/gmail/nossr50/runnables/database/SQLDatabaseKeepaliveTask.java b/src/main/java/com/gmail/nossr50/runnables/database/SQLDatabaseKeepaliveTask.java new file mode 100644 index 000000000..14ce54c11 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/runnables/database/SQLDatabaseKeepaliveTask.java @@ -0,0 +1,39 @@ +package com.gmail.nossr50.runnables.database; + +import java.lang.ref.WeakReference; + +import org.bukkit.scheduler.BukkitRunnable; + +import com.gmail.nossr50.database.SQLDatabaseManager; + +/** + * This task is in charge of sending a MySQL ping over the MySQL connection + * every hour to prevent the connection from timing out and losing players' + * data when they join. + *

+ * A WeakReference is used to keep the database instance, because + * {@link com.gmail.nossr50.commands.database.ConvertDatabaseCommand database + * conversion} may create a SQLDatabaseManager that will be thrown out. If a + * normal reference was used, the conversion would cause a combined data and + * resource leak through this task. + */ +public class SQLDatabaseKeepaliveTask extends BukkitRunnable { + WeakReference databaseInstance; + + public SQLDatabaseKeepaliveTask(SQLDatabaseManager dbman) { + databaseInstance = new WeakReference(dbman); + } + + public void run() { + SQLDatabaseManager dbman = databaseInstance.get(); + if (dbman != null) { + dbman.checkConnected(); + } + else { + // This happens when the database was started for a conversion, + // or discarded by its creator for any other reason. If this code + // was not present, we would leak the connection resources. + this.cancel(); + } + } +}