-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: PersisterPolicy/Builder #73
Comments
it seems reasonable but not that trivial. right now, store does not track timestamps of all data in persister, doing so will require assuming we know everything about the persister (e.g. no out of the band changes into persister and transactional guaratees between such key recording and real persistence of the data into persister). |
@yigit is there any sample code?
I could only find: https://github.com/dropbox/Store/blob/68276197441909be357fe31007b678f882a54be5/filesystem/src/main/java/com/dropbox/android/external/fs3/FileSystemPersister.kt in |
Another issue could be that is look difficult (impossible?) to call |
A problem I'm seeing is if I leave a screen and return to the screen immediately after, the fetcher still makes a network request, even though the response was cached seconds earlier. It was a wasted network call. I almost created a different bug, but I think this might fit into a PersisterPolicy concept... What if we had a lambda such as It would be a control value to determine whether or not the fetcher should be called when used with a persister.
|
I like the control value/shouldFetch idea. It seems fairly small of an addition which delegates the decision back to the user, lets see how others feel about it and then we can decide on an api |
Would something like this work for your use case? suspend inline fun <Key : Any, Output : Any> Store<Key, Output>.fetch(
key: Key,
forceFresh: Boolean = false,
crossinline doFreshIf: (Output) -> Boolean = { false }
): Output {
return if (forceFresh) {
// If we're forcing a fresh fetch, do it now
fresh(key)
} else {
// Else we'll check the current cached value
val cached = cachedOnly(key)
if (cached == null || doFreshIf(cached)) {
// Our cached value isn't valid, do a fresh fetch
fresh(key)
} else {
// We have a current cached value
cached
}
}
}
suspend fun <Key : Any, Output : Any> Store<Key, Output>.cachedOnly(key: Key): Output? {
return stream(StoreRequest.cached(key, refresh = false))
.filterNot { it is StoreResponse.Loading }
.first()
.dataOrNull()
} |
I don't recommend the null check because null can be a valid value. |
I agree that I would also want to use this with a stream call on a store that utilizes a persister. I'm not sure this is the best option considering we only need to use Then the stream call could take into account |
Ok, rather than using null what if we add an additional |
@digitalbuddha That sounds like it would work. I agree doing it at the store builder would be better rather than request level. My previous snippet was more to show I'm primarily using stream and would need the expired api to support stream. I use stream for both the primary store flow and my pull refresh flow. This allows me to get the StoreResponse data on pull refresh events and handle toggling loading state or showing errors. I then use first with a predicate to collect the refresh flow so it doesn't collect longer than needed. This has proven to be most useful so far over using a suspending call to fresh(). My primary flow I would want to take into account the expired so I don't hit the fetcher if the local cache is still valid, but for my pull refresh stream I would want to ignore expired and always hit the fetcher. |
@digitalbuddha I think the solution to this already exists. Upon further experimentation, my team has come this the following conclusion: Use the fetcher's block to handle the logic if the request should be made, etc... Here's a simple example:
We can see we already have the ability to do the requested checks if the call should be made based on cache validity as well as other logic if we wanted to. |
perfect! I'd prefer to keep our api surface small and can roll your example above into WIP recipes |
As I understand it, there is no way to specify the maximum number of items, total size, expiry time, purging policy etc. of locally persisted data items. This could lead to the unbounded growth of cached data and force the system to purge locally cached data or issue exceptions.
The responsibility is for the client to implement local cache purging, perhaps in the
writer
method, or as a background service.The use case for using
Store
as a image/video caching library would seem to require such functionality. Is this beyond the scope of the project?Thanks.
The text was updated successfully, but these errors were encountered: