Optimize: move ALL DB writes off main thread + increase auto-save to 2min
Spark showed 5.66% server thread from auto-save. Breakdown: - store() DB write: 1.39% (already moved to background) - StoreCurios DB write: 0.56% (was on main thread) - storeAccessories DB write: 0.55% (was on main thread) - storeCosmeticArmor DB write: 0.56% (was on main thread) - storeNeoForgeAttachments DB write: 0.58% (was on main thread) - storeSophisticatedStorage: 0.69% (was on main thread) - storeSophisticatedBackpacks: 0.59% (was on main thread) Changes: 1. Curios snapshot: new snapshotCuriosData() reads entity state on main thread (fast), returns serialized string. DB write in background. 2. ALL mod saves moved to background thread lambda: - ModCompatSync.storeAll (Accessories, CosmeticArmor, Attachments) - Sophisticated Backpacks/Storage/RS2 3. Auto-save interval doubled: 1200 -> 2400 ticks (1min -> 2min) 4. Main thread now only does: entity snapshot (~0.3ms) + curios snapshot Expected: ~80% reduction in main thread usage (5.66% -> ~1%) Vyrriox
This commit is contained in:
parent
7613f4ecfb
commit
04a1f0128e
|
|
@ -1037,11 +1037,9 @@ public class VanillaSync {
|
|||
}
|
||||
}
|
||||
|
||||
// Mod data snapshots - also on main thread (reads entity state safely)
|
||||
// Sophisticated Backpacks/Storage/RS2 are saved via their own store methods
|
||||
if (ModList.get().isLoaded("sophisticatedbackpacks")) ModsSupport.storeSophisticatedBackpacks(player);
|
||||
if (ModList.get().isLoaded("sophisticatedstorage")) ModsSupport.storeSophisticatedStorageItems(player);
|
||||
if (ModList.get().isLoaded("refinedstorage")) ModsSupport.storeRefinedStorageDisks(player);
|
||||
// NOTE: Sophisticated Backpacks/Storage/RS2 saves are NOT done here anymore.
|
||||
// They are done in the background thread (their entity reads are on SavedData which is thread-safe,
|
||||
// and their DB writes should not block the main thread).
|
||||
|
||||
return new PlayerDataSnapshot(
|
||||
uuid, XP, score, foodLevel, health,
|
||||
|
|
@ -1099,7 +1097,7 @@ public class VanillaSync {
|
|||
private static int heartbeatTickCounter = 0;
|
||||
private static final int HEARTBEAT_INTERVAL_TICKS = 600; // Every 30 seconds (20 tps * 30s)
|
||||
private static int autoSaveTickCounter = 0;
|
||||
private static final int AUTO_SAVE_INTERVAL_TICKS = 1200; // Every minute
|
||||
private static final int AUTO_SAVE_INTERVAL_TICKS = 2400; // Every 2 minutes (was 1min, doubled to reduce main thread load)
|
||||
private static int autoCleanCuriosCacheTickCounter = 0;
|
||||
private static final int AUTO_CLEAN_CURIOS_CACHE_INTERVAL_TICKS = 36000; // Every 30 min
|
||||
|
||||
|
|
@ -1137,24 +1135,40 @@ public class VanillaSync {
|
|||
ReentrantLock lock = getPlayerLock(puuid);
|
||||
if (!lock.tryLock()) continue;
|
||||
try {
|
||||
// === MAIN THREAD: Snapshot entity data + mod data (reads are fast) ===
|
||||
// === MAIN THREAD: Snapshot ALL data (entity reads only, no DB I/O) ===
|
||||
final PlayerDataSnapshot snapshot = snapshotPlayerData(player);
|
||||
// Curios/Accessories/CosmeticArmor/Attachments have their own DB writes internally,
|
||||
// but they READ entity state here on the main thread (safe)
|
||||
|
||||
// Snapshot Curios data on main thread (entity read), DB write deferred
|
||||
final String curiosSnapshot;
|
||||
if (ModList.get().isLoaded("curios") && !player.isDeadOrDying()) {
|
||||
new ModsSupport().StoreCurios(player, false);
|
||||
}
|
||||
if (!player.isDeadOrDying()) {
|
||||
ModCompatSync.storeAll(player);
|
||||
curiosSnapshot = ModsSupport.snapshotCuriosData(player);
|
||||
} else {
|
||||
curiosSnapshot = null;
|
||||
}
|
||||
|
||||
// === BACKGROUND THREAD: Write main snapshot to DB (slow, off main thread) ===
|
||||
// Use tryLock in the background task to skip if logout already saved newer data
|
||||
// === BACKGROUND THREAD: ALL DB writes in one batch ===
|
||||
executorService.submit(() -> {
|
||||
ReentrantLock bgLock = getPlayerLock(puuid);
|
||||
if (!bgLock.tryLock()) return; // logout won the race, skip stale snapshot
|
||||
if (!bgLock.tryLock()) return;
|
||||
try {
|
||||
writeSnapshotToDB(snapshot);
|
||||
// Write curios data
|
||||
if (curiosSnapshot != null) {
|
||||
JDBCsetUp.executePreparedUpdate(
|
||||
"REPLACE INTO curios (uuid, curios_item) VALUES (?, ?)",
|
||||
puuid, curiosSnapshot);
|
||||
}
|
||||
// Mod compat + storage saves (all DB writes, off main thread)
|
||||
ModCompatSync.storeAll(player);
|
||||
if (ModList.get().isLoaded("sophisticatedbackpacks")) {
|
||||
ModsSupport.storeSophisticatedBackpacks(player);
|
||||
}
|
||||
if (ModList.get().isLoaded("sophisticatedstorage")) {
|
||||
ModsSupport.storeSophisticatedStorageItems(player);
|
||||
}
|
||||
if (ModList.get().isLoaded("refinedstorage")) {
|
||||
ModsSupport.storeRefinedStorageDisks(player);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
PlayerSync.LOGGER.error("Error auto-saving player {}", puuid, e);
|
||||
} finally {
|
||||
|
|
|
|||
|
|
@ -234,6 +234,28 @@ public class ModsSupport {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Snapshots Curios data into a serialized string on the main thread (no DB write).
|
||||
* Returns the serialized data string, or null if no curios data.
|
||||
*/
|
||||
public static String snapshotCuriosData(Player player) {
|
||||
if (!ModList.get().isLoaded("curios")) return null;
|
||||
Optional<ICuriosItemHandler> handlerOpt = CuriosApi.getCuriosInventory(player);
|
||||
Map<String, String> flatMap = new HashMap<>();
|
||||
handlerOpt.ifPresent(handler -> {
|
||||
handler.getCurios().forEach((slotType, stacksHandler) -> {
|
||||
IDynamicStackHandler dynStacks = stacksHandler.getStacks();
|
||||
for (int i = 0; i < dynStacks.getSlots(); i++) {
|
||||
ItemStack stack = dynStacks.getStackInSlot(i);
|
||||
if (!stack.isEmpty()) {
|
||||
flatMap.put(slotType + ":" + i, VanillaSync.getNbtForStorage(stack));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return flatMap.toString();
|
||||
}
|
||||
|
||||
public void StoreCurios(Player player, boolean init) throws SQLException {
|
||||
if (!ModList.get().isLoaded("curios")) return;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user