feat: Implement caching and rate limiting for API requests

This commit is contained in:
2026-10-18 17:20:29 +03:00
parent 3dc6cc4e9e
commit 6b68cec34a
12 changed files with 282 additions and 27 deletions

View File

@@ -22,7 +22,7 @@ class ScheduleApp : Application() {
override fun onCreate() {
super.onCreate()
settings = Settings(this)
repository = Repository(this, Api(BuildConfig.API_URL), settings)
repository = Repository(this, Api(BuildConfig.API_URL, cacheDir), settings)
notes = NotesStore(this)
attendance = AttendanceStore(this)
Reminders.createChannel(this)

View File

@@ -6,10 +6,12 @@ import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.Cache
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.File
import java.io.IOException
import java.util.concurrent.TimeUnit
@@ -22,9 +24,12 @@ val json = Json {
}
/** The schedule server's HTTP API. Every error message is ready to show. */
class Api(baseUrl: String) {
class Api(baseUrl: String, cacheDir: File? = null) {
private val base: HttpUrl = baseUrl.toHttpUrl()
private val client = OkHttpClient.Builder()
// The server marks answers "no-cache" with an ETag: OkHttp keeps them here and asks
// again with If-None-Match, so an unchanged semester comes back as an empty 304.
.apply { if (cacheDir != null) cache(Cache(File(cacheDir, "http"), 10L * 1024 * 1024)) }
.connectTimeout(10, TimeUnit.SECONDS)
// The first request after a server start can wait for the catalog index.
.readTimeout(60, TimeUnit.SECONDS)

View File

@@ -17,7 +17,6 @@ data class Timetable(
val days: List<Day> = emptyList(),
val weekly: List<WeeklyDay> = emptyList(),
val notes: List<String> = emptyList(),
val generatedAt: String? = null,
)
@Serializable