Eduard Boloș
01/23/2023, 5:24 PMreplay = 1
to prevent re-running the same query for each downstream flow. My doubt is: does the scope passed to shareIn()
operator need to be canceled at some point, to avoid leaking resources? Or if using WhileSubscribed
for the started strategy it's fine if it's not closed? We assumed that it needs closing, so in our first iteration we are passing viewModelScope
in the repository function, but we would actually prefer the repository to have its own scope instead, so we don't have to pass this all the time. But if it has its own scope, we need to manually cancel the scope from somewhere (probably ViewModel.onCleared()
?), which also is not very convenient.
Here's some sample code to better illustrate this situation: https://gist.github.com/eduardb/8916ac63d7a279b48857d9abc1f4546e. What are your thoughts?kevin.cianfarini
01/23/2023, 5:32 PMDue to how we use Apollo Kotlin and DataBinding in our Android app, we realised while migrating from LiveData to Flows that we need to share the Flow that is returned by our repository withIs there any reason you’re using the flow variant over the single-shot suspend funs? If you’re using the normalized cache, I’d recommend having a strict line between a request that hits the network and a request that reads from the cache. That means not usingto prevent re-running the same query for each downstream flow.replay = 1
CacheFirst
or NetworkFirst
at all, and only ever using NetworkOnly
and CacheOnly
.
A shared/state flow will always live in memory if something is referencing it, including a coroutinescope or any other non-coroutines related object. If you are using Flow.shareIn
or Flow.stateIn
that scope will have to get cancelled to garbage collect the associated shared/state flow.Eduard Boloș
01/23/2023, 5:51 PMIs there any reason you’re using the flow variant over the single-shot suspend funs? If you’re using the normalized cache, I’d recommend having a strict line between a request that hits the network and a request that reads from the cache. That means not usingWe are doing the equivalent oforCacheFirst
at all, and only ever usingNetworkFirst
andNetworkOnly
.CacheOnly
CacheOnly
, but instead of Query.Data
, we read Fragment.Data
from the normalized cache, it's a longer story. But at the same time, we have some NetworkOnly
queries that run in the background to refresh the cache. We do all of this because it's very important for us for the app to work while offline because of poor connectivity conditions in our markets, but we also want data on the screen to be refreshed instantly when something in the normalized cache is updated (e.g. as a result of successful refresh).
A shared/state flow will always live in memory if something is referencing it, including a coroutinescope or any other non-coroutines related object. If you are usingThis confirms my assumption, thanks! Any novel ideas on how to make it less cumbersome to cancel the repository's scope when it's not used anymore? 😄orFlow.shareIn
that scope will have to get cancelled to garbage collect the associated shared/state flow.Flow.stateIn
kevin.cianfarini
01/23/2023, 6:07 PMCacheOnly
. It’s not expensive to do so since it never hits the network. It would save you a lot of heartache for managing a scope for your repositories.