From 6135b1ad6844479b005e31b23f47e5c504dd3c1e Mon Sep 17 00:00:00 2001 From: jbock Date: Thu, 10 Oct 2024 13:29:36 +0200 Subject: [PATCH] some server side cleanup --- src/main/java/com/bernd/ActiveGames.java | 30 ++++++++----------- .../java/com/bernd/CleanupController.java | 29 +++++++++++++++--- src/main/java/com/bernd/GameController.java | 7 ++--- src/main/java/com/bernd/Games.java | 4 +++ src/main/java/com/bernd/LobbyController.java | 18 +++++------ src/main/java/com/bernd/OpenGames.java | 5 ++-- .../bernd/SessionDisconnectEventListener.java | 3 +- .../java/com/bernd/model/ActiveGameList.java | 6 ---- src/main/java/com/bernd/model/Game.java | 11 +++++-- .../java/com/bernd/model/OpenGameList.java | 6 ---- src/main/java/com/bernd/model/StatusMap.java | 24 +++++++-------- 11 files changed, 78 insertions(+), 65 deletions(-) delete mode 100644 src/main/java/com/bernd/model/ActiveGameList.java delete mode 100644 src/main/java/com/bernd/model/OpenGameList.java diff --git a/src/main/java/com/bernd/ActiveGames.java b/src/main/java/com/bernd/ActiveGames.java index 412b6fe..e1b555a 100644 --- a/src/main/java/com/bernd/ActiveGames.java +++ b/src/main/java/com/bernd/ActiveGames.java @@ -1,40 +1,36 @@ package com.bernd; import com.bernd.model.ActiveGame; -import com.bernd.model.ActiveGameList; +import com.bernd.model.Game; import com.bernd.model.StatusMap; -import org.springframework.stereotype.Component; - import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.Set; +import org.springframework.stereotype.Component; @Component public class ActiveGames { private final StatusMap statusMap; - private final Map cache = new LinkedHashMap<>(); + private final Games games; - ActiveGames(StatusMap statusMap) { + ActiveGames( + StatusMap statusMap, + Games games) { this.statusMap = statusMap; + this.games = games; } - ActiveGame put(ActiveGame game) { - cache.put(game.id(), game); - return game; - } - - ActiveGameList games() { + List games() { Set active = statusMap.activeGames(); List result = new ArrayList<>(active.size()); for (String gameId : active) { - ActiveGame game = cache.get(gameId); - if (game != null) { - result.add(game); + Game game = games.get(gameId); + if (game == null) { + continue; } + result.add(game.toActiveGame()); } - return new ActiveGameList(result); + return result; } } diff --git a/src/main/java/com/bernd/CleanupController.java b/src/main/java/com/bernd/CleanupController.java index d360018..722be3a 100644 --- a/src/main/java/com/bernd/CleanupController.java +++ b/src/main/java/com/bernd/CleanupController.java @@ -1,22 +1,31 @@ package com.bernd; +import com.bernd.model.Game; +import com.bernd.model.OpenGame; import com.bernd.model.StatusMap; import com.bernd.util.Sender; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - import java.util.List; import java.util.Map; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; @Component public class CleanupController { private final Sender sender; private final StatusMap statusMap; + private final OpenGames openGames; + private final Games games; - CleanupController(Sender sender, StatusMap statusMap) { + CleanupController( + Sender sender, + StatusMap statusMap, + OpenGames openGames, + Games games) { this.sender = sender; this.statusMap = statusMap; + this.openGames = openGames; + this.games = games; } @Scheduled(fixedDelay = 40 * 1000) @@ -27,5 +36,17 @@ public void runScheduled() { List users = e.getValue(); sender.sendUsers(room, users); } + List games = this.games.games(); + for (Game game : games) { + if (updatedRooms.getOrDefault(game.id(), List.of()).isEmpty()) { + this.games.remove(game.id()); + } + } + List openGames = this.openGames.games(); + for (OpenGame game : openGames) { + if (!statusMap.contains(game.user())) { + this.openGames.remove(game.user()); + } + } } } diff --git a/src/main/java/com/bernd/GameController.java b/src/main/java/com/bernd/GameController.java index 1dd7556..fe6f22d 100644 --- a/src/main/java/com/bernd/GameController.java +++ b/src/main/java/com/bernd/GameController.java @@ -148,7 +148,7 @@ public OpenGame newGame(@RequestBody OpenGame game) { String principal = getPrincipal(); OpenGame result = openGames.put(game.withUser(principal) .withId(RandomString.get())); - operations.convertAndSend("/topic/lobby/open_games", openGames.games()); + operations.convertAndSend("/topic/lobby/open_games", Map.of("games", openGames.games())); return result; } @@ -158,7 +158,6 @@ public ResponseEntity start(@RequestBody AcceptRequest acceptRequest) { openGames.remove(acceptRequest.opponent()); OpenGame openGame = openGames.remove(principal); Game fullGame = games.put(openGame.accept(acceptRequest)); - activeGames.put(ActiveGame.fromGame(fullGame)); Chat chat = chats.get(openGame.id()); ChatMessage startMessage = ChatMessage.createStartMessage(chat, fullGame); @@ -167,8 +166,8 @@ public ResponseEntity start(@RequestBody AcceptRequest acceptRequest) { operations.convertAndSend("/topic/gamestart", Map.of( "players", List.of(principal, acceptRequest.opponent()), "id", openGame.id())); - operations.convertAndSend("/topic/lobby/open_games", openGames.games()); - operations.convertAndSend("/topic/lobby/active_games", activeGames.games()); + operations.convertAndSend("/topic/lobby/open_games", Map.of("games", openGames.games())); + operations.convertAndSend("/topic/lobby/active_games", Map.of("games", activeGames.games())); return ResponseEntity.ok().build(); } diff --git a/src/main/java/com/bernd/Games.java b/src/main/java/com/bernd/Games.java index a61cc2c..8c27e67 100644 --- a/src/main/java/com/bernd/Games.java +++ b/src/main/java/com/bernd/Games.java @@ -22,4 +22,8 @@ Game put(Game game) { List games() { return List.copyOf(map.values()); } + + void remove(String id) { + map.remove(id); + } } diff --git a/src/main/java/com/bernd/LobbyController.java b/src/main/java/com/bernd/LobbyController.java index ec625d0..23c4ecb 100644 --- a/src/main/java/com/bernd/LobbyController.java +++ b/src/main/java/com/bernd/LobbyController.java @@ -2,15 +2,16 @@ import com.bernd.game.MoveList; import com.bernd.model.ActiveGame; -import com.bernd.model.ActiveGameList; import com.bernd.model.Chat; import com.bernd.model.ChatMessage; import com.bernd.model.Game; import com.bernd.model.MatchRequest; -import com.bernd.model.OpenGameList; +import com.bernd.model.OpenGame; import com.bernd.model.ViewGame; import com.bernd.util.Auth; import com.bernd.util.RandomString; +import java.util.List; +import java.util.Map; import org.springframework.http.ResponseEntity; import org.springframework.messaging.core.MessageSendingOperations; import org.springframework.stereotype.Controller; @@ -44,21 +45,21 @@ public class LobbyController { @GetMapping(value = "/api/lobby/hello") public ResponseEntity sayHello() { String principal = Auth.getPrincipal(); - operations.convertAndSend("/topic/lobby/open_games", openGames.games()); - operations.convertAndSend("/topic/lobby/active_games", activeGames.games()); + operations.convertAndSend("/topic/lobby/open_games", Map.of("games", openGames.games())); + operations.convertAndSend("/topic/lobby/active_games", Map.of("games", activeGames.games())); return ResponseEntity.ok().build(); } @ResponseBody @GetMapping(value = "/api/lobby/active_games") - public ActiveGameList getActiveGames() { - return activeGames.games(); + public Map> getActiveGames() { + return Map.of("games", activeGames.games()); } @ResponseBody @GetMapping(value = "/api/lobby/open_games") - public OpenGameList getOpenGames() { - return openGames.games(); + public Map> getOpenGames() { + return Map.of("games", openGames.games()); } @ResponseBody @@ -77,7 +78,6 @@ public ViewGame startEdit(@RequestBody MatchRequest request) { request.handicap(), new int[]{-1, -1}, MoveList.create(request.dim()))); - activeGames.put(ActiveGame.fromGame(game)); Chat chat = chats.get(game.id()); ChatMessage startMessage = ChatMessage.createStartMessage(chat, game); chat.messages().add(startMessage); diff --git a/src/main/java/com/bernd/OpenGames.java b/src/main/java/com/bernd/OpenGames.java index 2ab4ce4..6726056 100644 --- a/src/main/java/com/bernd/OpenGames.java +++ b/src/main/java/com/bernd/OpenGames.java @@ -2,7 +2,6 @@ import com.bernd.model.AcceptRequest; import com.bernd.model.OpenGame; -import com.bernd.model.OpenGameList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -27,8 +26,8 @@ OpenGame addRequest(String name, AcceptRequest request, String opponent) { return result; } - OpenGameList games() { - return new OpenGameList(List.copyOf(map.values())); + List games() { + return List.copyOf(map.values()); } OpenGame remove(String name) { diff --git a/src/main/java/com/bernd/SessionDisconnectEventListener.java b/src/main/java/com/bernd/SessionDisconnectEventListener.java index 42bf070..415033d 100644 --- a/src/main/java/com/bernd/SessionDisconnectEventListener.java +++ b/src/main/java/com/bernd/SessionDisconnectEventListener.java @@ -2,6 +2,7 @@ import com.bernd.util.RoomManager; import java.security.Principal; +import java.util.Map; import org.springframework.context.ApplicationListener; import org.springframework.messaging.core.MessageSendingOperations; import org.springframework.stereotype.Component; @@ -32,6 +33,6 @@ public void onApplicationEvent(SessionDisconnectEvent event) { String name = user.getName(); roomManager.logout(name); openGames.remove(name); - operations.convertAndSend("/topic/lobby/open_games", openGames.games()); + operations.convertAndSend("/topic/lobby/open_games", Map.of("games", openGames.games())); } } diff --git a/src/main/java/com/bernd/model/ActiveGameList.java b/src/main/java/com/bernd/model/ActiveGameList.java deleted file mode 100644 index a7e9316..0000000 --- a/src/main/java/com/bernd/model/ActiveGameList.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.bernd.model; - -import java.util.List; - -public record ActiveGameList(List games) { -} diff --git a/src/main/java/com/bernd/model/Game.java b/src/main/java/com/bernd/model/Game.java index ea320a2..2b66e5a 100644 --- a/src/main/java/com/bernd/model/Game.java +++ b/src/main/java/com/bernd/model/Game.java @@ -7,11 +7,10 @@ import com.bernd.game.Toggle; import com.bernd.util.BoardUpdateImpl; import com.bernd.util.Util; +import java.util.Objects; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.Objects; - import static com.bernd.game.Board.removeDeadStonesAround; import static com.bernd.util.Util.COLORS; @@ -235,4 +234,12 @@ public boolean isTimeout() { public boolean isCounting() { return state == STATE_COUNTING; } + + public ActiveGame toActiveGame() { + return new ActiveGame( + id, + black, + white, + board().length); + } } diff --git a/src/main/java/com/bernd/model/OpenGameList.java b/src/main/java/com/bernd/model/OpenGameList.java deleted file mode 100644 index 51e2323..0000000 --- a/src/main/java/com/bernd/model/OpenGameList.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.bernd.model; - -import java.util.List; - -public record OpenGameList(List games) { -} diff --git a/src/main/java/com/bernd/model/StatusMap.java b/src/main/java/com/bernd/model/StatusMap.java index 85e371b..3c4466f 100644 --- a/src/main/java/com/bernd/model/StatusMap.java +++ b/src/main/java/com/bernd/model/StatusMap.java @@ -45,12 +45,12 @@ public List usersInRoom(String room) { } /** - * @return all changed rooms, where inactive users have been removed + * @return a map where key=roomId and value=users */ public Map> removeInactiveUsers() { long current = System.currentTimeMillis(); Map> tmp = new HashMap<>(); - List removeTasks = new ArrayList<>(); + List usersToRemove = new ArrayList<>(); for (Map.Entry e : map.entrySet()) { UserStatus status = e.getValue(); String room = status.room(); @@ -58,22 +58,23 @@ public Map> removeInactiveUsers() { if (status.isActive(current)) { tmp.computeIfAbsent(room, key -> new ArrayList<>()).add(user); } else { - removeTasks.add(new RemoveTask(user, room)); + usersToRemove.add(user); } } - Map> result = new LinkedHashMap<>(Math.max(8, (int) (tmp.size() * 1.5))); - for (RemoveTask task : removeTasks) { - result.put(task.room, tmp.getOrDefault(task.room, List.of())); - map.remove(task.user); + for (String user : usersToRemove) { + UserStatus status = map.get(user); + if (status == null) { + continue; + } + map.remove(user); } - return result; + return tmp; } public Set activeGames() { Set result = new LinkedHashSet<>(); - long current = System.currentTimeMillis(); for (UserStatus status : map.values()) { - if (status.isActive(current)) { + if (!"lobby".equals(status.room())) { result.add(status.room()); } } @@ -83,7 +84,4 @@ public Set activeGames() { public boolean contains(String user) { return map.containsKey(user); } - - private record RemoveTask(String user, String room) { - } }