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.
*
* @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
*/
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.

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

Loading…
Cancel
Save