Problem
PlayerMoveWhileTeleporting runs a SQLite query on every PlayerMoveEvent. Bukkit fires that event many times per second for every online player who is walking or just turning their head, and each time the listener does:
Dao<TeleportAttempt> tad = new TeleportAttemptsDao();
TeleportAttempt ta = tad.get(event.getPlayer());
(src/main/java/com/samleighton/sethomestwo/events/PlayerMoveWhileTeleporting.java lines 19-20), which is a synchronous select * from player_teleport_attempts where player_uuid = ? on the main thread.
A teleport attempt only exists for the few seconds of a /home countdown, so on a normal server almost every one of those reads returns nothing. The cost scales with player count and movement, not with teleports. It shows up clearly with debugLevel: info, where the console fills with the statement several times a second while a single player walks around, but the queries run just the same at the default error level; they are only invisible.
Not a bug in behaviour (cancel-on-move works), a performance and hygiene issue that would get worse on a busy server.
Proposed direction
Keep an in-memory set of player UUIDs that currently have a pending teleport attempt, and make the move listener return immediately unless the player is in it, so the database is only touched during an actual countdown.
- Add to the set where
Home.teleport saves the attempt (teleportAttemptsDao.save(new TeleportAttempt(...))), remove it wherever the attempt is deleted: completed teleport, cancelled by movement, onDisable cleanup, and the stale-attempt purge in onEnable.
PlayerMoveWhileTeleporting checks the set first, then falls through to today's DAO logic (TeleportAttempt.canTeleport is computed from the saved start location, so nothing else changes).
- The
player_teleport_attempts table stays as the source of truth so attempts still survive a restart the way they do today; the set is only a fast pre-check.
- MockBukkit test: a player with no pending attempt moving triggers no query (assert via a counting hook or by observing no
STMT log line), and the existing cancel-on-move test still passes.
Optionally, when cancelOnMove is false the listener already returns before the query, so no change there.
Acceptance criteria
Found while doing the in-game check for #29 (bStats metrics); unrelated to that branch, which does not touch this listener.
Problem
PlayerMoveWhileTeleportingruns a SQLite query on everyPlayerMoveEvent. Bukkit fires that event many times per second for every online player who is walking or just turning their head, and each time the listener does:(
src/main/java/com/samleighton/sethomestwo/events/PlayerMoveWhileTeleporting.javalines 19-20), which is a synchronousselect * from player_teleport_attempts where player_uuid = ?on the main thread.A teleport attempt only exists for the few seconds of a
/homecountdown, so on a normal server almost every one of those reads returns nothing. The cost scales with player count and movement, not with teleports. It shows up clearly withdebugLevel: info, where the console fills with the statement several times a second while a single player walks around, but the queries run just the same at the defaulterrorlevel; they are only invisible.Not a bug in behaviour (cancel-on-move works), a performance and hygiene issue that would get worse on a busy server.
Proposed direction
Keep an in-memory set of player UUIDs that currently have a pending teleport attempt, and make the move listener return immediately unless the player is in it, so the database is only touched during an actual countdown.
Home.teleportsaves the attempt (teleportAttemptsDao.save(new TeleportAttempt(...))), remove it wherever the attempt is deleted: completed teleport, cancelled by movement,onDisablecleanup, and the stale-attempt purge inonEnable.PlayerMoveWhileTeleportingchecks the set first, then falls through to today's DAO logic (TeleportAttempt.canTeleportis computed from the saved start location, so nothing else changes).player_teleport_attemptstable stays as the source of truth so attempts still survive a restart the way they do today; the set is only a fast pre-check.STMTlog line), and the existing cancel-on-move test still passes.Optionally, when
cancelOnMoveis false the listener already returns before the query, so no change there.Acceptance criteria
debugLevel: infoshows noplayer_teleport_attemptsstatements from the move listener.Skipped: 0.Found while doing the in-game check for #29 (bStats metrics); unrelated to that branch, which does not touch this listener.