Skip to content

Commit

Permalink
added caching and fallback request
Browse files Browse the repository at this point in the history
  • Loading branch information
DatL4g committed May 3, 2024
1 parent 429d9e1 commit b1543e3
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import kotlin.time.Duration.Companion.hours

class AiringTodayRepository(
private val apolloClient: ApolloClient,
private val fallbackClient: ApolloClient,
private val nsfw: Flow<Boolean> = flowOf(false),
) {

Expand All @@ -24,8 +25,39 @@ class AiringTodayRepository(
private val airingPreFilter = query.transform {
return@transform emitAll(apolloClient.query(it.toGraphQL()).toFlow())
}
val airing = combine(airingPreFilter, nsfw) { q, n ->
State.fromGraphQL(q.data, n)
private val fallbackPreFilter = query.transform {
return@transform emitAll(fallbackClient.query(it.toGraphQL()).toFlow())
}
private val fallbackQuery = combine(fallbackPreFilter, nsfw.distinctUntilChanged()) { q, n ->
val data = q.data
if (data == null) {
if (q.hasErrors()) {
State.fromGraphQL(data, n)
} else {
null
}
} else {
State.fromGraphQL(data, n)
}
}.filterNotNull()

val airing = combine(airingPreFilter, nsfw.distinctUntilChanged()) { q, n ->
val data = q.data
if (data == null) {
if (q.hasErrors()) {
State.fromGraphQL(data, n)
} else {
null
}
} else {
State.fromGraphQL(data, n)
}
}.filterNotNull().transform {
return@transform if (it is State.Error) {
emitAll(fallbackQuery)
} else {
emit(it)
}
}

fun nextPage() = page.getAndUpdate {
Expand Down
57 changes: 0 additions & 57 deletions anilist/src/commonMain/kotlin/dev/datlag/aniflow/anilist/Cache.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,6 @@ import dev.datlag.tooling.async.suspendCatching
import kotlin.time.Duration.Companion.hours

internal object Cache {
private val trendingAnime = InMemoryKache<TrendingQuery, TrendingQuery.Data>(
maxSize = 5L * 1024 * 1024,
) {
strategy = KacheStrategy.LRU
expireAfterWriteDuration = 2.hours
}

private val airing = InMemoryKache<AiringQuery, AiringQuery.Data>(
maxSize = 5L * 1024 * 1024
) {
strategy = KacheStrategy.LRU
expireAfterWriteDuration = 1.hours
}

private val season = InMemoryKache<SeasonQuery, SeasonQuery.Data>(
maxSize = 5L * 1024 * 1024
) {
strategy = KacheStrategy.LRU
expireAfterWriteDuration = 2.hours
}

private val medium = InMemoryKache<MediumQuery, Medium>(
maxSize = 10L * 1024 * 1024
) {
Expand All @@ -43,42 +22,6 @@ internal object Cache {
expireAfterWriteDuration = 2.hours
}

suspend fun getTrending(key: TrendingQuery): TrendingQuery.Data? {
return suspendCatching {
trendingAnime.getIfAvailable(key)
}.getOrNull()
}

suspend fun setTrending(key: TrendingQuery, data: TrendingQuery.Data): TrendingQuery.Data {
return suspendCatching {
trendingAnime.put(key, data)
}.getOrNull() ?: data
}

suspend fun getAiring(key: AiringQuery): AiringQuery.Data? {
return suspendCatching {
airing.getIfAvailable(key)
}.getOrNull()
}

suspend fun setAiring(key: AiringQuery, data: AiringQuery.Data): AiringQuery.Data {
return suspendCatching {
airing.put(key, data)
}.getOrNull() ?: data
}

suspend fun getSeason(key: SeasonQuery): SeasonQuery.Data? {
return suspendCatching {
season.getIfAvailable(key)
}.getOrNull()
}

suspend fun setSeason(key: SeasonQuery, data: SeasonQuery.Data): SeasonQuery.Data {
return suspendCatching {
season.put(key, data)
}.getOrNull() ?: data
}

suspend fun getMedium(key: MediumQuery): Medium? {
return suspendCatching {
medium.getIfAvailable(key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import kotlinx.datetime.Clock

class PopularNextSeasonRepository(
private val apolloClient: ApolloClient,
private val fallbackClient: ApolloClient,
private val nsfw: Flow<Boolean> = flowOf(false),
) {

Expand All @@ -28,11 +29,40 @@ class PopularNextSeasonRepository(
year = year
)
}
private val fallbackQuery = query.transform {
return@transform emitAll(fallbackClient.query(it.toGraphQL()).toFlow())
}.mapNotNull {
val data = it.data
if (data == null) {
if (it.hasErrors()) {
SeasonState.fromGraphQL(data)
} else {
null
}
} else {
SeasonState.fromGraphQL(data)
}
}

val popularNextSeason = query.transform {
return@transform emitAll(apolloClient.query(it.toGraphQL()).toFlow())
}.map {
SeasonState.fromGraphQL(it.data)
}.mapNotNull {
val data = it.data
if (data == null) {
if (it.hasErrors()) {
SeasonState.fromGraphQL(data)
} else {
null
}
} else {
SeasonState.fromGraphQL(data)
}
}.transform {
return@transform if (it is SeasonState.Error) {
emitAll(fallbackQuery)
} else {
emit(it)
}
}

fun nextPage() = page.getAndUpdate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlinx.coroutines.flow.*

class PopularSeasonRepository(
private val apolloClient: ApolloClient,
private val fallbackClient: ApolloClient,
private val nsfw: Flow<Boolean> = flowOf(false),
) {

Expand All @@ -21,11 +22,40 @@ class PopularSeasonRepository(
nsfw = n
)
}
private val fallbackQuery = query.transform {
return@transform emitAll(fallbackClient.query(it.toGraphQL()).toFlow())
}.mapNotNull {
val data = it.data
if (data == null) {
if (it.hasErrors()) {
SeasonState.fromGraphQL(data)
} else {
null
}
} else {
SeasonState.fromGraphQL(data)
}
}

val popularThisSeason = query.transform {
return@transform emitAll(apolloClient.query(it.toGraphQL()).toFlow())
}.map {
SeasonState.fromGraphQL(it.data)
}.mapNotNull {
val data = it.data
if (data == null) {
if (it.hasErrors()) {
SeasonState.fromGraphQL(data)
} else {
null
}
} else {
SeasonState.fromGraphQL(data)
}
}.transform {
return@transform if (it is SeasonState.Error) {
emitAll(fallbackQuery)
} else {
emit(it)
}
}

fun nextPage() = page.getAndUpdate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlinx.coroutines.flow.*

class TrendingRepository(
private val apolloClient: ApolloClient,
private val fallbackClient: ApolloClient,
private val nsfw: Flow<Boolean> = flowOf(false),
) {

Expand All @@ -21,11 +22,40 @@ class TrendingRepository(
nsfw = n
)
}
private val fallbackQuery = query.transform {
return@transform emitAll(fallbackClient.query(it.toGraphQL()).toFlow())
}.mapNotNull {
val data = it.data
if (data == null) {
if (it.hasErrors()) {
State.fromGraphQL(data)
} else {
null
}
} else {
State.fromGraphQL(data)
}
}

val trending = query.transform {
return@transform emitAll(apolloClient.query(it.toGraphQL()).toFlow())
}.map {
State.fromGraphQL(it.data)
}.mapNotNull {
val data = it.data
if (data == null) {
if (it.hasErrors()) {
State.fromGraphQL(data)
} else {
null
}
} else {
State.fromGraphQL(data)
}
}.transform {
return@transform if (it is State.Error) {
emitAll(fallbackQuery)
} else {
emit(it)
}
}

fun nextPage() = page.getAndUpdate {
Expand Down
3 changes: 3 additions & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ kotlin {
implementation(libs.kache)
implementation(libs.markdown.renderer)

implementation(libs.apollo.cache)
implementation(libs.apollo.cache.sql)

implementation("dev.datlag.sheets-compose-dialogs:rating:2.0.0-SNAPSHOT")
implementation("dev.datlag.sheets-compose-dialogs:option:2.0.0-SNAPSHOT")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import androidx.datastore.core.DataStoreFactory
import androidx.datastore.core.okio.OkioStorage
import coil3.ImageLoader
import coil3.request.allowHardware
import com.apollographql.apollo3.cache.normalized.api.MemoryCacheFactory
import com.apollographql.apollo3.cache.normalized.api.NormalizedCacheFactory
import com.apollographql.apollo3.cache.normalized.sql.SqlNormalizedCacheFactory
import dev.datlag.aniflow.BuildKonfig
import dev.datlag.aniflow.Sekret
import dev.datlag.aniflow.firebase.FirebaseFactory
Expand Down Expand Up @@ -120,6 +123,11 @@ actual object PlatformModule {
bindSingleton<BurningSeriesResolver> {
BurningSeriesResolver(context = instance())
}
bindSingleton<NormalizedCacheFactory>(Constants.AniList.CACHE_FACTORY) {
MemoryCacheFactory(maxSizeBytes = 25 * 1024 * 1024).chain(
SqlNormalizedCacheFactory(context = instance(), name = "anilist.db")
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import coil3.svg.SvgDecoder
import com.apollographql.apollo3.ApolloClient
import com.apollographql.apollo3.api.http.HttpRequest
import com.apollographql.apollo3.api.http.HttpResponse
import com.apollographql.apollo3.cache.normalized.api.MemoryCacheFactory
import com.apollographql.apollo3.cache.normalized.api.NormalizedCacheFactory
import com.apollographql.apollo3.cache.normalized.normalizedCache
import com.apollographql.apollo3.network.http.HttpInterceptor
import com.apollographql.apollo3.network.http.HttpInterceptorChain
import de.jensklingenberg.ktorfit.Ktorfit
Expand Down Expand Up @@ -81,12 +84,14 @@ data object NetworkModule {
return chain.proceed(req)
}
})
.normalizedCache(instance(Constants.AniList.CACHE_FACTORY))
.build()
}
bindSingleton<ApolloClient>(Constants.AniList.FALLBACK_APOLLO_CLIENT) {
ApolloClient.Builder()
.dispatcher(ioDispatcher())
.serverUrl(Constants.AniList.SERVER_URL)
.normalizedCache(instance(Constants.AniList.CACHE_FACTORY))
.build()
}
bindSingleton<UserHelper> {
Expand Down Expand Up @@ -119,6 +124,7 @@ data object NetworkModule {

TrendingRepository(
apolloClient = instance(Constants.AniList.APOLLO_CLIENT),
fallbackClient = instance(Constants.AniList.FALLBACK_APOLLO_CLIENT),
nsfw = appSettings.adultContent
)
}
Expand All @@ -127,6 +133,7 @@ data object NetworkModule {

AiringTodayRepository(
apolloClient = instance(Constants.AniList.APOLLO_CLIENT),
fallbackClient = instance(Constants.AniList.FALLBACK_APOLLO_CLIENT),
nsfw = appSettings.adultContent
)
}
Expand All @@ -135,6 +142,7 @@ data object NetworkModule {

PopularSeasonRepository(
apolloClient = instance(Constants.AniList.APOLLO_CLIENT),
fallbackClient = instance(Constants.AniList.FALLBACK_APOLLO_CLIENT),
nsfw = appSettings.adultContent
)
}
Expand All @@ -143,6 +151,7 @@ data object NetworkModule {

PopularNextSeasonRepository(
apolloClient = instance(Constants.AniList.APOLLO_CLIENT),
fallbackClient = instance(Constants.AniList.FALLBACK_APOLLO_CLIENT),
nsfw = appSettings.adultContent
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ data object Constants {

data object AniList {
const val SERVER_URL = "https://graphql.anilist.co/"
const val CACHE_FACTORY = "AniListCacheFactory"
const val APOLLO_CLIENT = "AniListApolloClient"
const val FALLBACK_APOLLO_CLIENT = "FallbackAniListApolloClient"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.serialization.json.Json
import org.kodein.di.*
import org.publicvalue.multiplatform.oidc.appsupport.IosCodeAuthFlowFactory

actual object PlatformModule {

Expand Down Expand Up @@ -51,9 +50,6 @@ actual object PlatformModule {
localLogger = instanceOrNull()
)
}
bindEagerSingleton<IosCodeAuthFlowFactory> {
IosCodeAuthFlowFactory()
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ android-credentials-play-services = { group = "androidx.credentials", name = "cr
activity = { group = "androidx.activity", name = "activity-ktx", version.ref = "activity" }
activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activity" }
apollo = { group = "com.apollographql.apollo3", name = "apollo-runtime", version.ref = "apollo" }
apollo-cache = { group = "com.apollographql.apollo3", name = "apollo-normalized-cache", version.ref = "apollo" }
apollo-cache-sql = { group = "com.apollographql.apollo3", name = "apollo-normalized-cache-sqlite", version.ref = "apollo" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
atomicfu = { group = "org.jetbrains.kotlinx", name = "atomicfu-gradle-plugin", version.ref = "atomicfu" }
coil = { group = "io.coil-kt.coil3", name = "coil", version.ref = "coil" }
Expand Down

0 comments on commit b1543e3

Please sign in to comment.