aboutsummaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
authorLMBishop <13875753+LMBishop@users.noreply.github.com>2021-03-03 10:57:20 +0000
committerLMBishop <13875753+LMBishop@users.noreply.github.com>2021-03-03 10:57:20 +0000
commit882912269bf254b00880fdd0bdfefb9e43a754bc (patch)
tree66438e9a5fc0ce69ce7de148e1393346fe6e4bc1 /src/main
parent4a518069613a08b894abbb2707cc205749e95716 (diff)
Add option for asynchronous read/write on join/leave
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/leonardobishop/quests/QuestsAutosaveRunnable.java3
-rw-r--r--src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java8
-rw-r--r--src/main/java/com/leonardobishop/quests/obj/Options.java13
-rw-r--r--src/main/java/com/leonardobishop/quests/player/QPlayerManager.java22
-rw-r--r--src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java54
-rw-r--r--src/main/resources/config.yml2
6 files changed, 59 insertions, 43 deletions
diff --git a/src/main/java/com/leonardobishop/quests/QuestsAutosaveRunnable.java b/src/main/java/com/leonardobishop/quests/QuestsAutosaveRunnable.java
index 38a9f140..71e42dff 100644
--- a/src/main/java/com/leonardobishop/quests/QuestsAutosaveRunnable.java
+++ b/src/main/java/com/leonardobishop/quests/QuestsAutosaveRunnable.java
@@ -1,5 +1,6 @@
package com.leonardobishop.quests;
+import com.leonardobishop.quests.obj.Options;
import com.leonardobishop.quests.player.QPlayer;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@@ -37,7 +38,7 @@ public class QuestsAutosaveRunnable extends BukkitRunnable {
if (Bukkit.getPlayer(player) != null) {
QPlayer qPlayer = plugin.getPlayerManager().getPlayer(player);
- qPlayer.getQuestProgressFile().saveToDisk(true);
+ qPlayer.getQuestProgressFile().saveToDisk(Options.QUEST_AUTOSAVE_ASYNC.getBooleanValue());
}
}
diff --git a/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java b/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java
index 092289ca..5c12770d 100644
--- a/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java
+++ b/src/main/java/com/leonardobishop/quests/events/EventPlayerJoin.java
@@ -5,6 +5,7 @@ import com.leonardobishop.quests.obj.Messages;
import com.leonardobishop.quests.obj.Options;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerJoinEvent;
@@ -19,6 +20,13 @@ public class EventPlayerJoin implements Listener {
this.plugin = plugin;
}
+ @EventHandler(priority = EventPriority.MONITOR)
+ public void onAsyncJoin(AsyncPlayerPreLoginEvent event) {
+ if (!Options.QUEST_JOIN_ASYNC.getBooleanValue()) return;
+ UUID playerUuid = event.getUniqueId();
+ plugin.getPlayerManager().loadPlayer(playerUuid);
+ }
+
@EventHandler
public void onEvent(PlayerJoinEvent event) {
UUID playerUuid = event.getPlayer().getUniqueId();
diff --git a/src/main/java/com/leonardobishop/quests/obj/Options.java b/src/main/java/com/leonardobishop/quests/obj/Options.java
index 864dde37..0d8fdc2c 100644
--- a/src/main/java/com/leonardobishop/quests/obj/Options.java
+++ b/src/main/java/com/leonardobishop/quests/obj/Options.java
@@ -7,6 +7,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
public enum Options {
CATEGORIES_ENABLED("options.categories-enabled"),
@@ -25,6 +26,8 @@ public enum Options {
ALLOW_QUEST_CANCEL("options.allow-quest-cancel"),
ALLOW_QUEST_TRACK("options.allow-quest-track"),
QUEST_AUTOSAVE_ASYNC("options.performance-tweaking.quests-autosave-async"),
+ QUEST_JOIN_ASYNC("options.performance-tweaking.quests-join-async"),
+ QUEST_LEAVE_ASYNC("options.performance-tweaking.quests-leave-async"),
SOFT_CLEAN_QUESTSPROGRESSFILE_ON_JOIN("options.soft-clean-questsprogressfile-on-join"),
PUSH_SOFT_CLEAN_TO_DISK("options.tab-completion.push-soft-clean-to-disk"),
TAB_COMPLETE_ENABLED("options.tab-completion.enabled"),
@@ -38,7 +41,7 @@ public enum Options {
GLOBAL_QUEST_DISPLAY_LORE_APPEND_STARTED("global-quest-display.lore.append-started"),
GLOBAL_QUEST_DISPLAY_LORE_APPEND_TRACKED("global-quest-display.lore.append-tracked");
- private static final Map<String, Boolean> cachedBooleans = new HashMap<>();
+ private static final Map<String, Boolean> cachedBooleans = new ConcurrentHashMap<>();
private final String path;
@@ -63,13 +66,7 @@ public enum Options {
}
public boolean getBooleanValue() {
- Boolean val = cachedBooleans.get(path);
- if (val != null) {
- return val;
- } else {
- cachedBooleans.put(path, Quests.get().getConfig().getBoolean(path));
- return getBooleanValue();
- }
+ return cachedBooleans.computeIfAbsent(path, s -> Quests.get().getConfig().getBoolean(path));
}
public boolean getBooleanValue(boolean def) {
diff --git a/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java b/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java
index 955b55da..ac7504fe 100644
--- a/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java
+++ b/src/main/java/com/leonardobishop/quests/player/QPlayerManager.java
@@ -2,10 +2,12 @@ package com.leonardobishop.quests.player;
import com.leonardobishop.quests.Quests;
import com.leonardobishop.quests.QuestsLogger;
+import com.leonardobishop.quests.obj.Options;
import com.leonardobishop.quests.player.questprogressfile.QPlayerPreferences;
import com.leonardobishop.quests.player.questprogressfile.QuestProgress;
import com.leonardobishop.quests.player.questprogressfile.QuestProgressFile;
import com.leonardobishop.quests.player.questprogressfile.TaskProgress;
+import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
@@ -13,6 +15,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
public class QPlayerManager {
@@ -22,7 +25,7 @@ public class QPlayerManager {
this.plugin = plugin;
}
- private final Map<UUID, QPlayer> qPlayers = new HashMap<>();
+ private final Map<UUID, QPlayer> qPlayers = new ConcurrentHashMap<>();
/**
* Gets the QPlayer from a given UUID.
@@ -48,7 +51,7 @@ public class QPlayerManager {
*/
public void removePlayer(UUID uuid) {
plugin.getQuestsLogger().debug("Unloading and saving player " + uuid + ".");
- this.getPlayer(uuid).getQuestProgressFile().saveToDisk(false);
+ this.getPlayer(uuid).getQuestProgressFile().saveToDisk(Options.QUEST_LEAVE_ASYNC.getBooleanValue());
qPlayers.remove(uuid);
}
@@ -78,8 +81,8 @@ public class QPlayerManager {
* @param uuid the uuid of the player
*/
public void loadPlayer(UUID uuid) {
- plugin.getQuestsLogger().debug("Loading player " + uuid + " from disk.");
- if (qPlayers.get(uuid) == null) {
+ plugin.getQuestsLogger().debug("Loading player " + uuid + " from disk. Main thread: " + Bukkit.isPrimaryThread());
+ qPlayers.computeIfAbsent(uuid, s -> {
QuestProgressFile questProgressFile = new QuestProgressFile(uuid, new QPlayerPreferences(null), plugin);
try {
@@ -120,11 +123,10 @@ public class QPlayerManager {
// fuck
}
- QPlayer qPlayer = new QPlayer(uuid, questProgressFile, plugin);
-
- this.qPlayers.put(uuid, qPlayer);
- } else {
- plugin.getQuestsLogger().debug("Player " + uuid + " is already loaded.");
- }
+ return new QPlayer(uuid, questProgressFile, plugin);
+ });
+// else {
+// plugin.getQuestsLogger().debug("Player " + uuid + " is already loaded.");
+// }
}
}
diff --git a/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java
index 02337cfa..16ccd020 100644
--- a/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java
+++ b/src/main/java/com/leonardobishop/quests/player/questprogressfile/QuestProgressFile.java
@@ -3,7 +3,12 @@ package com.leonardobishop.quests.player.questprogressfile;
import com.leonardobishop.quests.Quests;
import com.leonardobishop.quests.api.QuestsAPI;
import com.leonardobishop.quests.api.enums.QuestStartResult;
-import com.leonardobishop.quests.api.events.*;
+import com.leonardobishop.quests.api.events.PlayerCancelQuestEvent;
+import com.leonardobishop.quests.api.events.PlayerFinishQuestEvent;
+import com.leonardobishop.quests.api.events.PlayerStartQuestEvent;
+import com.leonardobishop.quests.api.events.PlayerStartTrackQuestEvent;
+import com.leonardobishop.quests.api.events.PlayerStopTrackQuestEvent;
+import com.leonardobishop.quests.api.events.PreStartQuestEvent;
import com.leonardobishop.quests.obj.Messages;
import com.leonardobishop.quests.obj.Options;
import com.leonardobishop.quests.player.QPlayer;
@@ -13,11 +18,15 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
-import org.bukkit.scheduler.BukkitTask;
import java.io.File;
import java.io.IOException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class QuestProgressFile {
@@ -416,11 +425,23 @@ public class QuestProgressFile {
}
public void saveToDisk(boolean async) {
- plugin.getQuestsLogger().debug("Saving player " + playerUUID + " to disk.");
+ plugin.getQuestsLogger().debug("Saving player " + playerUUID + " to disk. Main thread: " + async);
+ List<QuestProgress> questProgressValues = new ArrayList<>(questProgress.values());
File directory = new File(plugin.getDataFolder() + File.separator + "playerdata");
if (!directory.exists() && !directory.isDirectory()) {
directory.mkdirs();
}
+
+ if (async) {
+ Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
+ save(questProgressValues);
+ });
+ } else {
+ save(questProgressValues);
+ }
+ }
+
+ private void save(List<QuestProgress> questProgressValues) {
File file = new File(plugin.getDataFolder() + File.separator + "playerdata" + File.separator + playerUUID.toString() + ".yml");
if (!file.exists()) {
try {
@@ -432,7 +453,7 @@ public class QuestProgressFile {
YamlConfiguration data = YamlConfiguration.loadConfiguration(file);
data.set("quest-progress", null);
- for (QuestProgress questProgress : questProgress.values()) {
+ for (QuestProgress questProgress : questProgressValues) {
data.set("quest-progress." + questProgress.getQuestId() + ".started", questProgress.isStarted());
data.set("quest-progress." + questProgress.getQuestId() + ".completed", questProgress.isCompleted());
data.set("quest-progress." + questProgress.getQuestId() + ".completed-before", questProgress.isCompletedBefore());
@@ -444,25 +465,10 @@ public class QuestProgressFile {
.getProgress());
}
}
-//
- synchronized (this) {
-
- // TODO
- if (async && Options.QUEST_AUTOSAVE_ASYNC.getBooleanValue()) {
- Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
- try {
- data.save(file);
- } catch (IOException e) {
- e.printStackTrace();
- }
- });
- } else {
- try {
- data.save(file);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
+ try {
+ data.save(file);
+ } catch (IOException e) {
+ e.printStackTrace();
}
}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index ce523a3b..b195d416 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -177,6 +177,8 @@ options:
quest-queue-executor-interval: 1 # how frequently Quests should execute the next check in the completion queue (def=1 - 0.05s) - increase this value if you are struggling with performance
quest-autosave-interval: 12000 # how frequently online players data will be autosaved (def=12000 - 10 minutes)
quests-autosave-async: false # experimental - save asynchronously on autosave
+ quests-join-async: false # experimental - load asynchronously on join
+ quests-leave-async: false # experimental - save asynchronously on leave
tab-completion:
enabled: true
error-checking: