mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 15:27:50 +07:00
Avoid OOM errors when updating all games by avoiding parallelization
This commit is contained in:
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user