Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.apollographql.cache.normalized

import com.apollographql.apollo.ApolloCall

enum class FetchPolicy {
/**
* Emit the response from the cache first, and if there was a cache miss, emit the response(s) from the network.
Expand All @@ -25,7 +27,9 @@ enum class FetchPolicy {

/**
* Emit the response from the cache first, and then emit the response(s) from the network.
*
* Warning: this can emit multiple successful responses, which is not allowed by [ApolloCall.execute] and will
* crash. Use only with [ApolloCall.toFlow] or [ApolloCall.watch].
*/
@Deprecated("This is equivalent of executing with CacheOnly and then with NetworkOnly")
CacheAndNetwork,
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.apollographql.cache.normalized

import com.apollographql.apollo.ApolloCall
import com.apollographql.apollo.api.ApolloRequest
import com.apollographql.apollo.api.ApolloResponse
import com.apollographql.apollo.api.Operation
Expand Down Expand Up @@ -42,11 +43,12 @@ val DefaultFetchPolicyInterceptor = object : ApolloInterceptor {
request = request
.newBuilder()
.fetchFromCache(true)
.build()
.build(),
).single()
.errorsAsException(throwOnCacheMiss = request.throwOnCacheMiss, serverErrorsAsCacheMisses = request.serverErrorsAsCacheMisses)
emit(cacheResponse.newBuilder().isLast(request.onlyIfCached || cacheResponse.exception == null)
.build()
emit(
cacheResponse.newBuilder().isLast(request.onlyIfCached || cacheResponse.exception == null)
.build(),
)
if (cacheResponse.exception == null) {
return@flow
Expand All @@ -70,7 +72,7 @@ val NetworkFirstInterceptor = object : ApolloInterceptor {
var networkException: ApolloException? = null

val networkResponses = chain.proceed(
request = request
request = request,
).onEach { response ->
if (response.exception != null && networkException == null) {
networkException = response.exception
Expand All @@ -94,7 +96,7 @@ val NetworkFirstInterceptor = object : ApolloInterceptor {
request = request
.newBuilder()
.fetchFromCache(true)
.build()
.build(),
).single()
.errorsAsException(throwOnCacheMiss = request.throwOnCacheMiss, serverErrorsAsCacheMisses = request.serverErrorsAsCacheMisses)
emit(cacheResponse)
Expand All @@ -104,16 +106,19 @@ val NetworkFirstInterceptor = object : ApolloInterceptor {

/**
* An interceptor that emits the response from the cache first, and then emits the response(s) from the network.
*
* Warning: this can emit multiple successful responses, which is not allowed by [ApolloCall.execute] and will
* crash. Use only with [ApolloCall.toFlow] or [ApolloCall.watch].
*
*/
@Deprecated("This is equivalent of executing with onlyIfCached(true) followed by noCache(true)")
val CacheAndNetworkInterceptor = object : ApolloInterceptor {
override fun <D : Operation.Data> intercept(request: ApolloRequest<D>, chain: ApolloInterceptorChain): Flow<ApolloResponse<D>> {
return flow {
val cacheResponse = chain.proceed(
request = request
.newBuilder()
.fetchFromCache(true)
.build()
.build(),
).single()
.errorsAsException(throwOnCacheMiss = request.throwOnCacheMiss, serverErrorsAsCacheMisses = request.serverErrorsAsCacheMisses)

Expand Down Expand Up @@ -171,11 +176,13 @@ private fun <D : Operation.Data> ApolloResponse<D>.errorsAsException(
when {
cacheMissException != null -> {
newBuilder()
.exception(cacheMissException.apply {
if (cachedErrorException != null) {
addSuppressed(cachedErrorException)
}
})
.exception(
cacheMissException.apply {
if (cachedErrorException != null) {
addSuppressed(cachedErrorException)
}
},
)
.data(null)
.errors(null)
.build()
Expand Down Expand Up @@ -224,9 +231,9 @@ internal object FetchPolicyRouterInterceptor : ApolloInterceptor {
it.cacheInfo!!.newBuilder()
.cacheMissException(exceptions.filterIsInstance<CacheMissException>().firstOrNull())
.networkException(exceptions.firstOrNull { it !is CacheMissException })
.build()
.build(),
)
.build()
.build(),
)
hasEmitted = true
}
Expand All @@ -248,9 +255,9 @@ internal object FetchPolicyRouterInterceptor : ApolloInterceptor {
emit(
ApolloResponse.Builder(request.operation, request.requestUuid)
.exception(exception)
.build()
.build(),

)
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal val <D : Operation.Data> ApolloRequest<D>.fetchPolicyInterceptor
* This only has effects for queries. Mutations and subscriptions always use [FetchPolicy.NetworkOnly]
*/
fun <T> MutableExecutionOptions<T>.fetchPolicyInterceptor(interceptor: ApolloInterceptor) = addExecutionContext(
FetchPolicyContext(interceptor)
FetchPolicyContext(interceptor),
)

/**
Expand All @@ -45,11 +45,9 @@ fun <T> MutableExecutionOptions<T>.fetchPolicy(fetchPolicy: FetchPolicy): T {
FetchPolicy.CacheOnly -> onlyIfCached(true)
FetchPolicy.NetworkOnly -> noCache(true)
FetchPolicy.CacheFirst -> this as T
@Suppress("DEPRECATION")
FetchPolicy.CacheAndNetwork,
-> {
// CacheAndNetwork is deprecated but should still work
@Suppress("DEPRECATION")
fetchPolicyInterceptor(CacheAndNetworkInterceptor)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal val <T> MutableExecutionOptions<T>.refetchPolicyInterceptor
* Sets the [FetchPolicy] used when watching queries and a cache change has been published
*/
fun <T> MutableExecutionOptions<T>.refetchPolicyInterceptor(interceptor: ApolloInterceptor) = addExecutionContext(
RefetchPolicyContext(interceptor)
RefetchPolicyContext(interceptor),
)

/**
Expand All @@ -41,11 +41,8 @@ fun <T> MutableExecutionOptions<T>.refetchPolicy(fetchPolicy: FetchPolicy): T {
FetchPolicy.CacheOnly -> refetchOnlyIfCached(true)
FetchPolicy.NetworkOnly -> refetchNoCache(true)
FetchPolicy.CacheFirst -> this as T
@Suppress("DEPRECATION")
FetchPolicy.CacheAndNetwork,
-> {
// CacheAndNetwork is deprecated but should still work
@Suppress("DEPRECATION")
refetchPolicyInterceptor(CacheAndNetworkInterceptor)
}
}
Expand Down