server: improved performance and stability with broken AI and human games, e.g. less memory leaks and out of memory errors with AI (related to #11285, #5023);

This commit is contained in:
Oleg Agafonov 2025-06-29 00:59:31 +04:00
parent 5626079be9
commit dfb84b09f3
5 changed files with 14 additions and 17 deletions

View file

@ -157,7 +157,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
@Override
public boolean isNeedCancel() {
return this.needCancel || (this.errorCount > MAX_ERRORS_COUNT_BEFORE_CANCEL) || Thread.interrupted();
return this.needCancel || (this.errorCount > MAX_ERRORS_COUNT_BEFORE_CANCEL) || Thread.currentThread().isInterrupted();
}
private void setNeedCancel(boolean needCancel) {

View file

@ -213,10 +213,8 @@ public class ComputerPlayer6 extends ComputerPlayer {
logger.trace("Add Action [" + depth + "] " + node.getAbilities().toString() + " a: " + alpha + " b: " + beta);
}
Game game = node.getGame();
if (!COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS
&& Thread.interrupted()) {
Thread.currentThread().interrupt();
logger.debug("interrupted");
if (!COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS && Thread.currentThread().isInterrupted()) {
logger.debug("AI game sim interrupted by timeout");
return GameStateEvaluator2.evaluate(playerId, game).getTotalScore();
}
// Condition to stop deeper simulation
@ -476,10 +474,8 @@ public class ComputerPlayer6 extends ComputerPlayer {
}
protected int simulatePriority(SimulationNode2 node, Game game, int depth, int alpha, int beta) {
if (!COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS
&& Thread.interrupted()) {
Thread.currentThread().interrupt();
logger.info("interrupted");
if (!COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS && Thread.currentThread().isInterrupted()) {
logger.debug("AI game sim interrupted by timeout");
return GameStateEvaluator2.evaluate(playerId, game).getTotalScore();
}
node.setGameValue(game.getState().getValue(true).hashCode());
@ -507,9 +503,7 @@ public class ComputerPlayer6 extends ComputerPlayer {
int bestValSubNodes = Integer.MIN_VALUE;
for (Ability action : allActions) {
actionNumber++;
if (!COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS
&& Thread.interrupted()) {
Thread.currentThread().interrupt();
if (!COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS && Thread.currentThread().isInterrupted()) {
logger.info("Sim Prio [" + depth + "] -- interrupted");
break;
}

View file

@ -29,8 +29,7 @@ public final class EtaliPrimalStorm extends CardImpl {
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Whenever Etali, Primal Storm attacks, exile the top card of each player's library,
// then you may cast any number of nonland cards exiled this way without paying their mana costs.
// Whenever Etali, Primal Storm attacks, exile the top card of each player's library, then you may cast any number of nonland cards exiled this way without paying their mana costs.
this.addAbility(new AttacksTriggeredAbility(new EtaliPrimalStormEffect(), false));
}

View file

@ -897,7 +897,9 @@ public abstract class GameImpl implements Game {
numLosers++;
}
}
if (remainingPlayers <= 1 || numLosers >= state.getPlayers().size() - 1) {
boolean noMorePlayers = remainingPlayers <= 1 || numLosers >= state.getPlayers().size() - 1;
// stop on no more players or on stopped game sim thread
if (noMorePlayers || Thread.currentThread().isInterrupted()) {
end();
if (remainingPlayers == 0 && logger.isDebugEnabled()) {
logger.debug("DRAW for gameId: " + getId());

View file

@ -2834,8 +2834,10 @@ public abstract class PlayerImpl implements Player, Serializable {
}
@Override
public boolean canRespond() { // abort is checked here to get out of player requests (as example: after disconnect)
return isInGame() && !abort;
public boolean canRespond() {
// abort is checked here to get out of player requests (as example: after disconnect)
// thread is checked here to get out of AI game simulations or close by third party tools
return isInGame() && !abort && !Thread.currentThread().isInterrupted();
}
@Override