Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Splits persistently stored games and events by game type #64

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Splits persistently stored games and events into 'regular' games, i.e…
…. training games and events, and tournament game and events. In preparation for index state management lifecycle
  • Loading branch information
Oskar Jedvert committed Jan 7, 2022
commit 72f1ee79a0c2e4e41741a9dcaa0d34f21a6c5a4d
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,20 @@ public class GameHistory extends ApiMessage {

private final List<GameMessage> messages;

private final boolean isTrainingGame;
@JsonCreator
public GameHistory(
@JsonProperty("gameId") String gameId,
@JsonProperty("playerNames") String[] playerNames,
@JsonProperty("gameDate") LocalDateTime gameDate,
@JsonProperty("messages") List<GameMessage> messages) {
@JsonProperty("messages") List<GameMessage> messages,
@JsonProperty("isTrainingGame") boolean isTrainingGame) {

this.gameId = gameId;
this.playerNames = playerNames;
this.gameDate = gameDate;
this.messages = messages;
this.isTrainingGame = isTrainingGame;
}

public String getGameId() {
Expand All @@ -51,4 +55,8 @@ public LocalDateTime getGameDate() {
public List<GameMessage> getMessages() {
return messages;
}

public boolean isTrainingGame() {
return isTrainingGame;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void testSerialization() throws Exception {
List<GameMessage> gameMessages = new ArrayList<>();
gameMessages.add(new GameStartingEvent(gameId, 3, 46, 34, new GameSettings()));

GameHistory gh = new GameHistory(gameId, players, now, gameMessages);
GameHistory gh = new GameHistory(gameId, players, now, gameMessages, false);

String msg = ApiMessageParser.encodeMessage(gh);
System.out.println(msg);
Expand Down
12 changes: 10 additions & 2 deletions app/src/main/java/se/cygni/paintbot/event/InternalGameEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ public class InternalGameEvent {
private final long tstamp;
private GameMessage gameMessage;

public InternalGameEvent(long tstamp) {
private final boolean isTraining;

public InternalGameEvent(long tstamp, boolean isTraining) {
this.tstamp = tstamp;
this.isTraining = isTraining;
}

public InternalGameEvent(long tstamp, GameMessage gameMessage) {
public InternalGameEvent(long tstamp, GameMessage gameMessage, boolean isTraining) {
this.tstamp = tstamp;
this.gameMessage = gameMessage;
this.isTraining = isTraining;
}

public long getTstamp() {
Expand All @@ -31,4 +35,8 @@ public void onGameAborted(String gameId) {
public void onGameChanged(String gameId) {
this.gameMessage = GameMessageConverter.onGameChanged(gameId);
}

public boolean isTraining() {
return isTraining;
}
}
8 changes: 6 additions & 2 deletions app/src/main/java/se/cygni/paintbot/game/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ public boolean isEnded() {
return gameEngine.isGameComplete();
}

public boolean isTrainingGame() {
return trainingGame;
}

public GameResult getGameResult() {
return gameEngine.getGameResult();
}
Expand Down Expand Up @@ -233,14 +237,14 @@ public void abort() {
playerManager.clear();
gameEngine.abort();

InternalGameEvent gevent = new InternalGameEvent(System.currentTimeMillis());
InternalGameEvent gevent = new InternalGameEvent(System.currentTimeMillis(), this.trainingGame);
gevent.onGameAborted(getGameId());
globalEventBus.post(gevent);
globalEventBus.post(gevent.getGameMessage());
}

public void publishGameChanged() {
InternalGameEvent gevent = new InternalGameEvent(System.currentTimeMillis());
InternalGameEvent gevent = new InternalGameEvent(System.currentTimeMillis(), this.trainingGame);
gevent.onGameChanged(getGameId());
globalEventBus.post(gevent);
}
Expand Down
5 changes: 3 additions & 2 deletions app/src/main/java/se/cygni/paintbot/game/GameEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ private void notifyPlayers(Set<IPlayer> players, GameMessage message) {

InternalGameEvent gevent = new InternalGameEvent(
System.currentTimeMillis(),
message);
message,
this.gameFeatures.isTrainingGame());
globalEventBus.post(gevent);
}

Expand Down Expand Up @@ -304,7 +305,7 @@ public GameResult getGameResult() {
}

public void publishGameChanged() {
InternalGameEvent gevent = new InternalGameEvent(System.currentTimeMillis());
InternalGameEvent gevent = new InternalGameEvent(System.currentTimeMillis(), this.gameFeatures.isTrainingGame());
gevent.onGameChanged(gameId);
globalEventBus.post(gevent);
}
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/se/cygni/paintbot/game/GameManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ private void registerGame(Game game) {
log.info("Registered new game, posting to GlobalEventBus...");
globalEventBus.post(new InternalGameEvent(
System.currentTimeMillis(),
new GameCreatedEvent(game.getGameId())));
new GameCreatedEvent(game.getGameId()),
game.isTrainingGame()));
}

@Subscribe
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,18 @@ private GameHistory getGameHistory(String gameId) {
gameId,
getPlayersForGame(gameId),
extractGameDate(gameId),
getGameMessagesForGame(gameId));
getGameMessagesForGame(gameId),
isTrainingGame(gameId));
}

private boolean isTrainingGame(String gameId) {
Optional<InternalGameEvent> firstMapUpdate = getFirstInternalGameEvent(gameId);

if(firstMapUpdate.isPresent()) {
return firstMapUpdate.get().isTraining();
}

return false;
}

private List<GameMessage> getGameMessagesForGame(String gameId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ public class GameHistoryStorageElastic implements GameHistoryStorage {
@Value("${paintbot.elastic.gamehistory.type}")
private String gameHistoryType;

@Value("${paintbot.elastic.tournamenthistory.index}")
private String tournamentHistoryIndex;

@Value("${paintbot.elastic.tournamenthistory.type}")
private String tournamentHistoryType;

@Value("${paintbot.elastic.tournamentevent.index}")
private String tournamentEventIndex;

@Value("${paintbot.elastic.tournamentevent.type}")
private String tournamentEventType;

@Value("${paintbot.elastic.gameevent.index}")
private String gameEventIndex;

Expand All @@ -71,7 +83,14 @@ public void addGameHistory(GameHistory gameHistory) {

String eventId = UUID.randomUUID().toString();
try {
IndexRequest indexRequest = new IndexRequest(gameEventIndex, gameEventType, eventId);
IndexRequest indexRequest;

if (gameHistory.isTrainingGame()) {
indexRequest = new IndexRequest(gameEventIndex, gameEventType, eventId);
} else {
indexRequest = new IndexRequest(tournamentEventIndex, tournamentEventType, eventId);
}

String msg = GameMessageParser.encodeMessage(gameMessage);
indexRequest.source(msg, XContentType.JSON);
elasticClient.index(indexRequest);
Expand All @@ -83,10 +102,17 @@ public void addGameHistory(GameHistory gameHistory) {
GameHistoryPersisted ghp = new GameHistoryPersisted(
gameHistory.getGameId(),
gameHistory.getPlayerNames(),
gameHistory.getGameDate()
gameHistory.getGameDate(),
gameHistory.isTrainingGame()
);

IndexRequest indexRequest = new IndexRequest(gameHistoryIndex, gameHistoryType, gameHistory.getGameId());
IndexRequest indexRequest;
if (gameHistory.isTrainingGame()) {
indexRequest = new IndexRequest(gameHistoryIndex, gameHistoryType, gameHistory.getGameId());
} else {
indexRequest = new IndexRequest(tournamentHistoryIndex, tournamentHistoryType, gameHistory.getGameId());
}

String msg = ApiMessageParser.encodeMessage(ghp);
indexRequest.source(msg, XContentType.JSON);
elasticClient.index(indexRequest);
Expand All @@ -104,6 +130,16 @@ public Optional<GameHistory> getGameHistory(String gameId) {

try {
SearchResponse esResponse = elasticClient.search(searchRequest);

if (esResponse.getHits().totalHits == 0) {
searchRequest = new SearchRequest(tournamentHistoryIndex);
searchSourceBuilder = new SearchSourceBuilder()
.query(QueryBuilders.idsQuery(tournamentHistoryType).addIds(gameId));
searchRequest.source(searchSourceBuilder);

esResponse = elasticClient.search(searchRequest);
}

if (esResponse.getHits().totalHits > 0) {
GameHistoryPersisted ghp = (GameHistoryPersisted) ApiMessageParser.decodeMessage(esResponse.getHits().getAt(0).getSourceAsString());
List<GameMessage> gameMessages = getGameEventsForGame(gameId);
Expand All @@ -112,7 +148,8 @@ public Optional<GameHistory> getGameHistory(String gameId) {
ghp.getGameId(),
ghp.getPlayerNames(),
ghp.getGameDate(),
gameMessages
gameMessages,
ghp.isTrainingGame()
);

return Optional.of(gameHistory);
Expand Down Expand Up @@ -143,6 +180,21 @@ private List<GameMessage> getGameEventsForGame(String gameId) {
return messages;
}

if (scrollResp.getHits().totalHits == 0) {
searchRequest = new SearchRequest(tournamentEventIndex)
.scroll(new TimeValue(60000));
searchSourceBuilder = new SearchSourceBuilder()
.query(qb)
.size(200);
searchRequest.source(searchSourceBuilder);

try {
scrollResp = elasticClient.search(searchRequest);
} catch (IOException e) {
log.error("Failed to search ElasticSearch");
return messages;
}
}

//Scroll until no hits are returned
while (true) {
Expand Down Expand Up @@ -198,6 +250,12 @@ private GameHistorySearchResult getGameHistorySearchResult(SearchSourceBuilder s
List<GameHistorySearchItem> items = new ArrayList<>();
try {
SearchResponse esResponse = elasticClient.search(searchRequest);
if (esResponse.getHits().totalHits == 0) {
searchRequest = new SearchRequest(tournamentHistoryIndex);
searchRequest.source(searchSourceBuilder);

esResponse = elasticClient.search(searchRequest);
}

Iterator<SearchHit> searchHitIterator = esResponse.getHits().iterator();
int counter = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class GameHistoryStorageInMemory implements GameHistoryStorage {
private final EventBus eventBus;

private List<GameHistory> gameHistories = Collections.synchronizedList(new ArrayList<>());
private List<GameHistory> tournamentHistories = Collections.synchronizedList(new ArrayList<>());

@Autowired
public GameHistoryStorageInMemory(EventBus eventBus) {
Expand All @@ -43,15 +44,28 @@ public GameHistoryStorageInMemory(EventBus eventBus) {
@Subscribe
public void addGameHistory(GameHistory gameHistory) {
log.debug("Adding GameHistory to memory!");
gameHistories.add(gameHistory);
if (gameHistory.isTrainingGame()) {
gameHistories.add(gameHistory);
} else {
tournamentHistories.add(gameHistory);
}
}

@Override
public Optional<GameHistory> getGameHistory(String gameId) {
return gameHistories
Optional<GameHistory> gh = gameHistories
.stream()
.filter(gameHistory -> gameHistory.getGameId().equals(gameId))
.findFirst();

if (gh.isEmpty()) {
return tournamentHistories
.stream()
.filter(gameHistory -> gameHistory.getGameId().equals(gameId))
.findFirst();
}

return gh;
}

@Override
Expand All @@ -70,6 +84,20 @@ public GameHistorySearchResult listGamesWithPlayer(String playerName) {
})
.collect(Collectors.toList());

if (items.isEmpty()) {
items = tournamentHistories
.stream()
.filter(gameHistory -> ArrayUtils.contains(gameHistory.getPlayerNames(), playerName))
.map(gameHistory -> {
return new GameHistorySearchItem(
gameHistory.getGameId(),
gameHistory.getPlayerNames(),
gameHistory.getGameDate()
);
})
.collect(Collectors.toList());
}

result.setItems(items);
return result;
}
Expand All @@ -83,6 +111,17 @@ public GameHistorySearchResult getHistoricGames() {
gameHistory.getPlayerNames(),
gameHistory.getGameDate()))
.collect(Collectors.toList()));

if (games.getItems().isEmpty()) {
games = new GameHistorySearchResult(
tournamentHistories.stream()
.map(gameHistory -> new GameHistorySearchItem(
gameHistory.getGameId(),
gameHistory.getPlayerNames(),
gameHistory.getGameDate()))
.collect(Collectors.toList()));
}

return games;
}

Expand All @@ -92,6 +131,11 @@ private void removeOldGames() {
GameHistory gameHistory = gameHistories.remove(0);
log.debug("Removed gameId: {}", gameHistory.getGameId());
}

while (tournamentHistories.size() > MAX_NOOF_GAMES_IN_MEMORY - 1) {
GameHistory gameHistory = tournamentHistories.remove(0);
log.debug("Removed gameId: {}", gameHistory.getGameId());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ public class GameHistoryPersisted extends ApiMessage {

private final LocalDateTime gameDate;

private final boolean isTrainingGame;
@JsonCreator
public GameHistoryPersisted(
@JsonProperty("gameId") String gameId,
@JsonProperty("playerNames") String[] playerNames,
@JsonProperty("gameDate") LocalDateTime gameDate) {
@JsonProperty("gameDate") LocalDateTime gameDate,
@JsonProperty("isTrainingGame") boolean isTrainingGame) {

this.gameId = gameId;
this.playerNames = playerNames;
this.gameDate = gameDate;
this.isTrainingGame = isTrainingGame;
}

public String getGameId() {
Expand All @@ -42,4 +45,8 @@ public String[] getPlayerNames() {
public LocalDateTime getGameDate() {
return gameDate;
}

public boolean isTrainingGame() {
return isTrainingGame;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ private void completeTournament() {

InternalGameEvent gevent = new InternalGameEvent(
System.currentTimeMillis(),
tee);
tee, false);
globalEventBus.post(gevent);
globalEventBus.post(gevent.getGameMessage());
}
Expand Down
Loading