Avoid OOM errors when updating all games by avoiding parallelization

This commit is contained in:
yairm210
2024-11-19 08:50:59 +02:00
parent 0655cc63a4
commit a914571b8e
3 changed files with 22 additions and 22 deletions

View File

@ -14,10 +14,8 @@ import com.unciv.logic.multiplayer.storage.MultiplayerFileNotFoundException
import com.unciv.logic.multiplayer.storage.MultiplayerServer
import com.unciv.models.metadata.GameSettings
import com.unciv.ui.components.extensions.isLargerThan
import com.unciv.utils.Concurrency
import com.unciv.utils.Dispatcher
import com.unciv.utils.debug
import com.unciv.utils.launchOnThreadPool
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn
@ -94,21 +92,17 @@ class Multiplayer {
*
* Fires: [MultiplayerGameUpdateStarted], [MultiplayerGameUpdated], [MultiplayerGameUpdateUnchanged], [MultiplayerGameUpdateFailed]
*/
fun requestUpdate(forceUpdate: Boolean = false, doNotUpdate: List<MultiplayerGame> = listOf()) {
Concurrency.run("Update all multiplayer games") {
val fileThrottleInterval = if (forceUpdate) Duration.ZERO else FILE_UPDATE_THROTTLE_PERIOD
// An exception only happens here if the files can't be listed, should basically never happen
throttle(lastFileUpdate, fileThrottleInterval, {}, action = {multiplayerFiles.updateSavesFromFiles()})
suspend fun requestUpdate(forceUpdate: Boolean = false, doNotUpdate: List<MultiplayerGame> = listOf()) {
val fileThrottleInterval = if (forceUpdate) Duration.ZERO else FILE_UPDATE_THROTTLE_PERIOD
// An exception only happens here if the files can't be listed, should basically never happen
throttle(lastFileUpdate, fileThrottleInterval, {}, action = {multiplayerFiles.updateSavesFromFiles()})
for (game in multiplayerFiles.savedGames.values) {
if (game in doNotUpdate) continue
// Any games that haven't been updated in 2 weeks (!) are inactive, don't waste your time
if (Duration.between(Instant.ofEpochMilli(game.fileHandle.lastModified()), Instant.now())
.isLargerThan(Duration.ofDays(14))) continue
launchOnThreadPool {
game.requestUpdate(forceUpdate)
}
}
for (game in multiplayerFiles.savedGames.values) {
if (game in doNotUpdate) continue
// Any games that haven't been updated in 2 weeks (!) are inactive, don't waste your time
if (Duration.between(Instant.ofEpochMilli(game.fileHandle.lastModified()), Instant.now())
.isLargerThan(Duration.ofDays(14))) continue
game.requestUpdate(forceUpdate) // DO NOT spawn in thread, since that leads to OOMs when many games try at once
}
}

View File

@ -58,8 +58,10 @@ class MultiplayerScreen : PickerScreen() {
setupHelpButton()
setupRightSideButton()
game.onlineMultiplayer.requestUpdate()
Concurrency.run("Update all multiplayer games") {
game.onlineMultiplayer.requestUpdate()
}
pickerPane.bottomTable.background = skinStrings.getUiBackground("MultiplayerScreen/BottomTable", tintColor = skinStrings.skinConfig.clearColor)
pickerPane.topTable.background = skinStrings.getUiBackground("MultiplayerScreen/TopTable", tintColor = skinStrings.skinConfig.clearColor)
@ -112,7 +114,11 @@ class MultiplayerScreen : PickerScreen() {
private fun createRefreshButton(): TextButton {
val btn = "Refresh list".toTextButton()
btn.onClick { game.onlineMultiplayer.requestUpdate() }
btn.onClick {
Concurrency.run("Update all multiplayer games") {
game.onlineMultiplayer.requestUpdate()
}
}
return btn
}

View File

@ -1399,7 +1399,7 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Building, Unit, Improvement
??? example "Costs [amount] [stockpiledResource]"
Do not confuse with "costs [amount] [stockpiledResource]" (lowercase 'c'), the Unit Action Modifier.
These resources are removed *when work begins* on the construction. Do not confuse with "costs [amount] [stockpiledResource]" (lowercase 'c'), the Unit Action Modifier.
Example: "Costs [3] [Mana]"
Applicable to: Building, Unit, Improvement
@ -1609,7 +1609,7 @@ Simple unique parameters are explained by mouseover. Complex parameters are expl
Applicable to: Building, Unit, Improvement
??? example "Costs [amount] [stockpiledResource]"
Do not confuse with "costs [amount] [stockpiledResource]" (lowercase 'c'), the Unit Action Modifier.
These resources are removed *when work begins* on the construction. Do not confuse with "costs [amount] [stockpiledResource]" (lowercase 'c'), the Unit Action Modifier.
Example: "Costs [3] [Mana]"
Applicable to: Building, Unit, Improvement
@ -2369,7 +2369,7 @@ If your mod renames Coast or Lakes, do not use this with one of these as paramet
Applicable to: Global, FollowerBelief, Improvement
??? example "Costs [amount] [stockpiledResource]"
Do not confuse with "costs [amount] [stockpiledResource]" (lowercase 'c'), the Unit Action Modifier.
These resources are removed *when work begins* on the construction. Do not confuse with "costs [amount] [stockpiledResource]" (lowercase 'c'), the Unit Action Modifier.
Example: "Costs [3] [Mana]"
Applicable to: Building, Unit, Improvement