Fix action history pagination to avoid loading all results (#5005)

Previously, getGameHistory loaded all action results with history.all
then paginated in-memory. For games with many actions, this caused
timeouts.

Now uses history.since(startIndex).take(limit) which efficiently loads
only the save files containing the requested range. The since() method
in PersistedHistory already calculates which partial game files to read.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-02 22:06:06 -08:00
committed by GitHub
co-authored by Claude Opus 4.5
parent 99037c7c3a
commit d125394028
@@ -657,10 +657,10 @@ class EagleServiceImpl(
gamesManager.gameControllerInfos.get(request.gameId) match {
case Some(controllerInfo) =>
val history = controllerInfo.controller.engine.history
val allResults = history.all
val totalCount = history.count
val startIndex = if request.startIndex > 0 then request.startIndex else 0
val limit = if request.limit > 0 then request.limit else allResults.length
val limit = if request.limit > 0 then request.limit else totalCount
implicit val formats: DefaultFormats.type = DefaultFormats
val monthNames = Vector(
@@ -678,11 +678,14 @@ class EagleServiceImpl(
"November",
"December"
)
val entries = allResults.zipWithIndex
.drop(startIndex)
// Use since(startIndex) for efficient partial loading instead of loading all results
val entries = history
.since(startIndex)
.take(limit)
.zipWithIndex
.map {
case (actionWithState, index) =>
case (actionWithState, localIndex) =>
val index = startIndex + localIndex
val ar = actionWithState.actionResult
val gs = actionWithState.gameState
val actionJson = writePretty(JsonFormat.toJson(ar))
@@ -708,7 +711,7 @@ class EagleServiceImpl(
GetGameHistoryResponse(
gameId = request.gameId,
totalActionCount = allResults.length,
totalActionCount = totalCount,
entries = entries
)