Fall back to last fetched ratings file on i/o error while updating
This commit is contained in:
@@ -7,6 +7,7 @@ import okhttp3.Request
|
||||
import org.jeudego.pairgoth.web.WebappManager
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.net.URL
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.time.LocalDate
|
||||
@@ -27,6 +28,7 @@ abstract class RatingsHandler(val origin: RatingsManager.Ratings) {
|
||||
lateinit var players: Json.Array
|
||||
lateinit var activeRatingsFile: File
|
||||
private var updated = false
|
||||
val ready get() = this::activeRatingsFile.isInitialized && this::players.isInitialized
|
||||
|
||||
val url: URL by lazy {
|
||||
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)
|
||||
}
|
||||
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 ratingsFilename = "${origin.name}-${ymd.format(lastUpdated)}.json"
|
||||
if (latestRatingsFile != null && latestRatingsFile.name == ratingsFilename) {
|
||||
@@ -87,15 +98,20 @@ abstract class RatingsHandler(val origin: RatingsManager.Ratings) {
|
||||
return players
|
||||
}
|
||||
|
||||
protected fun fetchPayload(): String {
|
||||
val request = Request.Builder()
|
||||
.url(url)
|
||||
.build()
|
||||
protected fun fetchPayload(): String? {
|
||||
try {
|
||||
val request = Request.Builder()
|
||||
.url(url)
|
||||
.build()
|
||||
|
||||
client.newCall(request).execute().use { response ->
|
||||
if (!response.isSuccessful) throw Error("Could not fetch $origin ratings: unexpected code $response")
|
||||
val contentType = response.headers["Content-Type"]?.toMediaType()
|
||||
return response.body!!.source().readString(contentType?.charset() ?: defaultCharset())
|
||||
client.newCall(request).execute().use { response ->
|
||||
if (!response.isSuccessful) throw IOException("Could not fetch $origin ratings: unexpected code $response")
|
||||
val contentType = response.headers["Content-Type"]?.toMediaType()
|
||||
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
|
||||
|
@@ -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()
|
||||
lateinit var players: Json.MutableArray
|
||||
@@ -139,7 +139,7 @@ object RatingsManager: Runnable {
|
||||
|
||||
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(),
|
||||
DateTimeFormatter.ISO_LOCAL_DATE.format(it.value.activeDate()))
|
||||
}.toMap()
|
||||
|
@@ -112,7 +112,7 @@
|
||||
</div>
|
||||
*#
|
||||
<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"/>
|
||||
<div class="search-param checkbox">
|
||||
<div class="circle"></div>
|
||||
@@ -121,7 +121,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<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"/>
|
||||
<div class="search-param checkbox">
|
||||
<div class="circle"></div>
|
||||
|
Reference in New Issue
Block a user