Fall back to last fetched ratings file on i/o error while updating

This commit is contained in:
Claude Brisson
2024-03-30 06:03:51 +01:00
parent 4f3e11d263
commit aefc567d29
3 changed files with 28 additions and 12 deletions

View File

@@ -7,6 +7,7 @@ import okhttp3.Request
import org.jeudego.pairgoth.web.WebappManager import org.jeudego.pairgoth.web.WebappManager
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.File import java.io.File
import java.io.IOException
import java.net.URL import java.net.URL
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.time.LocalDate import java.time.LocalDate
@@ -27,6 +28,7 @@ abstract class RatingsHandler(val origin: RatingsManager.Ratings) {
lateinit var players: Json.Array lateinit var players: Json.Array
lateinit var activeRatingsFile: File lateinit var activeRatingsFile: File
private var updated = false private var updated = false
val ready get() = this::activeRatingsFile.isInitialized && this::players.isInitialized
val url: URL by lazy { val url: URL by lazy {
WebappManager.properties.getProperty("ratings.${origin.name.lowercase(Locale.ROOT)}")?.let { URL(it) } ?: defaultURL WebappManager.properties.getProperty("ratings.${origin.name.lowercase(Locale.ROOT)}")?.let { URL(it) } ?: defaultURL
@@ -63,6 +65,15 @@ abstract class RatingsHandler(val origin: RatingsManager.Ratings) {
return initIfNeeded(latestRatingsFile) return initIfNeeded(latestRatingsFile)
} }
val payload = fetchPayload() val payload = fetchPayload()
if (payload == null) {
// an error occurred while fetching the payload, and has been reported
if (latestRatingsFile != null) {
// fall back to last ratings file
return initIfNeeded(latestRatingsFile)
} else {
return false
}
}
val (lastUpdated, lastPlayers) = parsePayload(payload) val (lastUpdated, lastPlayers) = parsePayload(payload)
val ratingsFilename = "${origin.name}-${ymd.format(lastUpdated)}.json" val ratingsFilename = "${origin.name}-${ymd.format(lastUpdated)}.json"
if (latestRatingsFile != null && latestRatingsFile.name == ratingsFilename) { if (latestRatingsFile != null && latestRatingsFile.name == ratingsFilename) {
@@ -87,15 +98,20 @@ abstract class RatingsHandler(val origin: RatingsManager.Ratings) {
return players return players
} }
protected fun fetchPayload(): String { protected fun fetchPayload(): String? {
val request = Request.Builder() try {
.url(url) val request = Request.Builder()
.build() .url(url)
.build()
client.newCall(request).execute().use { response -> client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw Error("Could not fetch $origin ratings: unexpected code $response") if (!response.isSuccessful) throw IOException("Could not fetch $origin ratings: unexpected code $response")
val contentType = response.headers["Content-Type"]?.toMediaType() val contentType = response.headers["Content-Type"]?.toMediaType()
return response.body!!.source().readString(contentType?.charset() ?: defaultCharset()) return response.body!!.source().readString(contentType?.charset() ?: defaultCharset())
}
} catch (ioe: IOException) {
logger.error("Could not refresh ${origin.name} ratings from ${url}", ioe)
return null
} }
} }
open fun defaultCharset() = StandardCharsets.UTF_8 open fun defaultCharset() = StandardCharsets.UTF_8

View File

@@ -36,7 +36,7 @@ object RatingsManager: Runnable {
); );
} }
fun activeMask() = ratingsHandlers.entries.filter { it.value.active }.map { it.key.flag }.reduce { a,b -> a or b } fun activeMask() = ratingsHandlers.entries.filter { it.value.active && it.value.ready }.map { it.key.flag }.reduce { a,b -> a or b }
val timer = Timer() val timer = Timer()
lateinit var players: Json.MutableArray lateinit var players: Json.MutableArray
@@ -139,7 +139,7 @@ object RatingsManager: Runnable {
val index = PlayerIndex() val index = PlayerIndex()
public fun getRatingsDates() = ratingsHandlers.filter{ it.value.active }.map { fun getRatingsDates() = ratingsHandlers.filter{ it.value.active && it.value.ready }.map {
Pair(it.key.name.lowercase(), Pair(it.key.name.lowercase(),
DateTimeFormatter.ISO_LOCAL_DATE.format(it.value.activeDate())) DateTimeFormatter.ISO_LOCAL_DATE.format(it.value.activeDate()))
}.toMap() }.toMap()

View File

@@ -112,7 +112,7 @@
</div> </div>
*# *#
<div class="two wide field"> <div class="two wide field">
<div class="toggle" title="$utils.ratingsDates.egf"> <div class="toggle" title="${utils.ratingsDates.egf|'no egf ratings'}">
<input id="egf" name="egf" type="checkbox" checked value="true"/> <input id="egf" name="egf" type="checkbox" checked value="true"/>
<div class="search-param checkbox"> <div class="search-param checkbox">
<div class="circle"></div> <div class="circle"></div>
@@ -121,7 +121,7 @@
</div> </div>
</div> </div>
<div class="two wide field"> <div class="two wide field">
<div class="toggle" title="$utils.ratingsDates.ffg"> <div class="toggle" title="${utils.ratingsDates.ffg|'no ffg ratings'}">
<input id="ffg" name="ffg" type="checkbox" checked value="true"/> <input id="ffg" name="ffg" type="checkbox" checked value="true"/>
<div class="search-param checkbox"> <div class="search-param checkbox">
<div class="circle"></div> <div class="circle"></div>