Fix deadlock on busy servers with small thread pools, close #100

feat/data-edit-commands
William 2 years ago
parent aec2836d1e
commit 5a000add98
No known key found for this signature in database

@ -114,10 +114,9 @@ public abstract class Database {
* <b>(Internal)</b> Prune user data for a given user to the maximum value as configured. * <b>(Internal)</b> Prune user data for a given user to the maximum value as configured.
* *
* @param user The user to prune data for * @param user The user to prune data for
* @return A future returning void when complete
* @implNote Data snapshots marked as {@code pinned} are exempt from rotation * @implNote Data snapshots marked as {@code pinned} are exempt from rotation
*/ */
protected abstract CompletableFuture<Void> rotateUserData(@NotNull User user); protected abstract void rotateUserData(@NotNull User user);
/** /**
* Deletes a specific {@link UserDataSnapshot} entry for a user from the database, by its UUID. * Deletes a specific {@link UserDataSnapshot} entry for a user from the database, by its UUID.

@ -297,27 +297,25 @@ public class MySqlDatabase extends Database {
} }
@Override @Override
protected CompletableFuture<Void> rotateUserData(@NotNull User user) { protected void rotateUserData(@NotNull User user) {
return CompletableFuture.runAsync(() -> { final List<UserDataSnapshot> unpinnedUserData = getUserData(user).join().stream()
final List<UserDataSnapshot> unpinnedUserData = getUserData(user).join().stream() .filter(dataSnapshot -> !dataSnapshot.pinned()).toList();
.filter(dataSnapshot -> !dataSnapshot.pinned()).toList(); if (unpinnedUserData.size() > plugin.getSettings().maxUserDataSnapshots) {
if (unpinnedUserData.size() > plugin.getSettings().maxUserDataSnapshots) { try (Connection connection = getConnection()) {
try (Connection connection = getConnection()) { try (PreparedStatement statement = connection.prepareStatement(formatStatementTables("""
try (PreparedStatement statement = connection.prepareStatement(formatStatementTables(""" DELETE FROM `%user_data_table%`
DELETE FROM `%user_data_table%` WHERE `player_uuid`=?
WHERE `player_uuid`=? AND `pinned` IS FALSE
AND `pinned` IS FALSE ORDER BY `timestamp` ASC
ORDER BY `timestamp` ASC LIMIT %entry_count%;""".replace("%entry_count%",
LIMIT %entry_count%;""".replace("%entry_count%", Integer.toString(unpinnedUserData.size() - plugin.getSettings().maxUserDataSnapshots))))) {
Integer.toString(unpinnedUserData.size() - plugin.getSettings().maxUserDataSnapshots))))) { statement.setString(1, user.uuid.toString());
statement.setString(1, user.uuid.toString()); statement.executeUpdate();
statement.executeUpdate();
}
} catch (SQLException e) {
plugin.log(Level.SEVERE, "Failed to prune user data from the database", e);
} }
} catch (SQLException e) {
plugin.log(Level.SEVERE, "Failed to prune user data from the database", e);
} }
}); }
} }
@Override @Override
@ -362,7 +360,8 @@ public class MySqlDatabase extends Database {
plugin.log(Level.SEVERE, "Failed to set user data in the database", e); plugin.log(Level.SEVERE, "Failed to set user data in the database", e);
} }
} }
}).thenRun(() -> rotateUserData(user).join()); this.rotateUserData(user);
});
} }
@Override @Override

Loading…
Cancel
Save