Skip to content

Commit

Permalink
Major Prison performance cleanup: When there are a few thousand playe…
Browse files Browse the repository at this point in the history
…rs on the server and in prison, prison was running in to major performance issues that was basically killing the performance of the server.

One major cause was with the startup routine of trying to add players that are on the server, but not in prison.  This could run for literally days and consume tons of processing resources.  So prison no longer tries to pre-add any player.  They have to join the server to be added.
The other major problem, was that if prison was trying to lookup a player that was not online, it would hit bukkit's offline players, and it would get a full list of all offline players.  This was horrible!  Bukkit would have to read all player files to generate the offline players listing, which could take a long time.  For example, with 46,000 players, it could take a few minutes for bukkit to fully load all players, and during that time, paper starts generating tons of warnings stating the server is not responding correctly.  It does not kill the server, but it generates mega bytes of errors in the log files.
So to fix this problem, prison no longer uses the bukkit offline player's functions unless trying to access ONE offline player using strictly their UUID.  A name search would require almost all files to be searched too.
As a result, prison is far more stable for very large player bases on servers!!  This is a major improvement.  In the past there has been complaints about prison when there were a lot of players, but I was never able to zero in on the problem since no one was really willing to work with me on figuring this out.  What helped a lot was being gifted over 46,000 players. :)  So now I can do some serious testing with many players.
  • Loading branch information
rbluer committed Dec 14, 2024
1 parent db08871 commit 1ebbbc2
Show file tree
Hide file tree
Showing 10 changed files with 378 additions and 189 deletions.
13 changes: 13 additions & 0 deletions docs/changelog_v3.3.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ These change logs represent the work that has been going on within prison.
# 3.3.0-alpha.19d 2024-10-11


2024-12-14

* **Prison was gifted over 46,000 players!!!**
Someone who was running in to performance issues with prison on a large server, gifted me over 46,000 players in both prison and in bukkit. Now I can perform various testing with larger player bases to help fix and prevent performance issues.


* **Major Prison performance cleanup:** When there are a few thousand players on the server and in prison, prison was running in to major performance issues that was basically killing the performance of the server.
One major cause was with the startup routine of trying to add players that are on the server, but not in prison. This could run for literally days and consume tons of processing resources. So prison no longer tries to pre-add any player. They have to join the server to be added.
The other major problem, was that if prison was trying to lookup a player that was not online, it would hit bukkit's offline players, and it would get a full list of all offline players. This was horrible! Bukkit would have to read all player files to generate the offline players listing, which could take a long time. For example, with 46,000 players, it could take a few minutes for bukkit to fully load all players, and during that time, paper starts generating tons of warnings stating the server is not responding correctly. It does not kill the server, but it generates mega bytes of errors in the log files.
So to fix this problem, prison no longer uses the bukkit offline player's functions unless trying to access ONE offline player using strictly their UUID. A name search would require almost all files to be searched too.
As a result, prison is far more stable for very large player bases on servers!! This is a major improvement. In the past there has been complaints about prison when there were a lot of players, but I was never able to zero in on the problem since no one was really willing to work with me on figuring this out. What helped a lot was being gifted over 46,000 players. :) So now I can do some serious testing with many players.


* **Rankup: would not work for ladders other than default and prestiges. Fixed.**


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,13 @@ private Player getPlayer( CommandSender sender, String playerName ) {
if ( playerName != null ) {
Optional<Player> opt = Prison.get().getPlatform().getPlayer( playerName );
if ( !opt.isPresent() ) {
opt = Prison.get().getPlatform().getOfflinePlayer( playerName );

result = Prison.get().getPlatform().getRankPlayer( null, playerName );
// opt = Prison.get().getPlatform().getOfflinePlayer( playerName );
}
if ( opt.isPresent() ) {

// if ( opt.isPresent() ) {
else {
result = opt.get();
}
}
Expand Down Expand Up @@ -2563,7 +2567,8 @@ private Player getPlayer( String playerName ) {
}
if ( player == null ) {

player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null );
player = Prison.get().getPlatform().getRankPlayer( null, playerName );
// player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null );
}
return player;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,31 @@ public Player getPlayer( CommandSender sender, String playerName, UUID uuid ) {
playerName = sender.getName();
}

if ( playerName != null ) {
Optional<Player> opt = Prison.get().getPlatform().getPlayer( playerName );
if ( !opt.isPresent() ) {
opt = Prison.get().getPlatform().getOfflinePlayer( playerName );
}
if ( opt.isPresent() ) {
result = opt.get();
}
}
if ( result == null && uuid != null ) {
Optional<Player> opt = Prison.get().getPlatform().getOfflinePlayer( uuid );
if ( opt.isPresent() ) {
result = opt.get();
}
}
result = Prison.get().getPlatform().getRankPlayer( uuid, playerName );


// if ( playerName != null ) {
// Optional<Player> opt = Prison.get().getPlatform().getPlayer( playerName );
//
// result = opt.orElse( null );
//
//// if ( !opt.isPresent() ) {
//// opt = Prison.get().getPlatform().getOfflinePlayer( playerName );
//// }
//// if ( opt.isPresent() ) {
//// result = opt.get();
//// }
// }
// if ( result == null && uuid != null ) {
//
//// result = Prison.get().getPlatform().getRankPlayer( uuid, playerName );
//
//// Optional<Player> opt = Prison.get().getPlatform().getOfflinePlayer( uuid );
//// if ( opt.isPresent() ) {
//// result = opt.get();
//// }
// }


// playerName = playerName != null && !playerName.trim().isEmpty() ?
// playerName : sender != null ? sender.getName() : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,25 +178,26 @@ public boolean checkPlaceholderKey(PlaceHolderKey placeHolderKey) {
public void setPlayer( UUID playerUuid, String playerName ) {
Player player = null;

if ( playerUuid != null ) {
player = Prison.get().getPlatform().getRankPlayer( playerUuid, playerName );

player = Prison.get().getPlatform().getPlayer( playerUuid ).orElse( null );
}

if ( player == null && playerName != null ) {

player = Prison.get().getPlatform().getPlayer( playerName ).orElse( null );
}

if ( player == null && playerUuid != null ) {

player = Prison.get().getPlatform().getOfflinePlayer( playerUuid ).orElse( null );
}

if ( player == null && playerName != null ) {

player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null );
}
// if ( playerUuid != null ) {
// player = Prison.get().getPlatform().getPlayer( playerUuid ).orElse( null );
// }
//
// if ( player == null && playerName != null ) {
//
// player = Prison.get().getPlatform().getPlayer( playerName ).orElse( null );
// }
//
// if ( player == null && playerUuid != null ) {
//
// player = Prison.get().getPlatform().getOfflinePlayer( playerUuid ).orElse( null );
// }
//
// if ( player == null && playerName != null ) {
//
// player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null );
// }


if ( player != null ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import tech.mcprison.prison.PrisonAPI;
import tech.mcprison.prison.convert.ConversionManager;
import tech.mcprison.prison.integration.IntegrationType;
import tech.mcprison.prison.internal.Player;
import tech.mcprison.prison.localization.LocaleManager;
import tech.mcprison.prison.modules.ModuleManager;
import tech.mcprison.prison.modules.ModuleStatus;
Expand Down Expand Up @@ -313,6 +312,13 @@ public boolean reloadRanksAndLadders() {
return success;
}

/**
* <p>This is actually a very bad idea to add any players that have not joined.
* This should be disabled. When a player joins the server for the first time,
* then it will add them successfully.
* </p>
*
*/
public void checkAllPlayersForJoin()
{

Expand All @@ -324,6 +330,8 @@ public void checkAllPlayersForJoin()

if ( addNewPlayers ) {

long startMs = System.currentTimeMillis();

RankUpCommand rankupCommands = rankManager.getRankupCommands();

// If there is a default rank on the default ladder, then
Expand All @@ -335,17 +343,33 @@ public void checkAllPlayersForJoin()
int addedPlayers = 0;
int fixedPlayers = 0;

for ( Player player : Prison.get().getPlatform().getOfflinePlayers() ) {

// getPlayer() will add a player who does not exist:
RankPlayer rPlayer = playerManager.getPlayer( player );
if ( rPlayer != null ) {
if ( rPlayer.checkName( player.getName() ) ) {
playerManager.savePlayer( rPlayer );
addedPlayers++;
}
}
}
List<RankPlayer> rPlayers = playerManager.getPlayers();

// NOTE: The Platform.getOfflinePlayers() only returns the playerManager.getPlayers() because
// bukkit can seriously lag the server and kill it.
// List<Player> players = Prison.get().getPlatform().getOfflinePlayers();
//
// String msg = String.format(
// "PrisonRanks: checkAllPlayersForJoin: Prison has %s players. Bukkit has %s. "
// + "Any player who is not in Prison will have to join prison to be added to prison.",
// Prison.get().getDecimalFormatInt().format( rPlayers.size() ),
// Prison.get().getDecimalFormatInt().format( players.size() )
// );
//
// Output.get().logInfo( msg );

// Prison will no longer add offline players. They must join to be added.
// for ( Player player : players ) {
//
// // getPlayer() will add a player who does not exist:
// RankPlayer rPlayer = playerManager.getPlayer( player );
// if ( rPlayer != null ) {
// if ( rPlayer.checkName( player.getName() ) ) {
// playerManager.savePlayer( rPlayer );
// addedPlayers++;
// }
// }
// }


RankPlayerFactory rankPlayerFactory = new RankPlayerFactory();
Expand All @@ -364,28 +388,28 @@ public void checkAllPlayersForJoin()
}


for ( RankPlayer rPlayer : playerManager.getPlayers() ) {
for ( RankPlayer rPlayer : rPlayers ) {

// @SuppressWarnings( "unused" )
// String rp = rPlayer.toString();

Rank rankOnDefault = null;
// Rank rankOnDefault = null;

PlayerRank pRank = rankPlayerFactory.getRank( rPlayer, defaultLadder );

if ( pRank != null ) {

rankOnDefault = pRank.getRank();

// Output.get().logInfo( "#### %s ladder = %s isRankNull= %s rank= %s %s [%s]" ,
// rPlayer.getName(),
// defaultLadder.getName(),
// (rankOnDefault == null ? "true" : "false"), (rankOnDefault == null ? "null" : rankOnDefault.getName()),
// (rankOnDefaultStr == null ? "true" : "false"), (rankOnDefaultStr == null ? "null" : rankOnDefaultStr.getName()),
// rp );

}
if ( rankOnDefault == null ) {
// if ( pRank != null ) {
//
// rankOnDefault = pRank.getRank();
//
//// Output.get().logInfo( "#### %s ladder = %s isRankNull= %s rank= %s %s [%s]" ,
//// rPlayer.getName(),
//// defaultLadder.getName(),
//// (rankOnDefault == null ? "true" : "false"), (rankOnDefault == null ? "null" : rankOnDefault.getName()),
//// (rankOnDefaultStr == null ? "true" : "false"), (rankOnDefaultStr == null ? "null" : rankOnDefaultStr.getName()),
//// rp );
//
// }
if ( pRank == null || pRank.getRank() == null ) {

rankupCommands.setPlayerRank( rPlayer, defaultRank );

Expand All @@ -406,7 +430,11 @@ public void checkAllPlayersForJoin()
}
}

Output.get().logInfo( "Ranks: Finished First Join Checks." );
long endMs = System.currentTimeMillis();

long duration = endMs - startMs;

Output.get().logInfo( "Ranks: Finished First Join Checks: " + duration + " ms" );
}
else {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ public PlayerRank getRank( RankPlayer rankPlayer, RankLadder ladder ) {
{
if ( key != null && key.getName().equalsIgnoreCase( ladder.getName() ) ) {
results = rankPlayer.getLadderRanks().get( key );
break;
}
}
}
Expand Down
Loading

0 comments on commit 1ebbbc2

Please sign in to comment.