-
Notifications
You must be signed in to change notification settings - Fork 215
DO NOT MERGE - WIP Make fetcher a class to avoid the API issues #139
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
Conversation
This CL changes Fetcher to be a function that returns value/error instead of throwing. Internally, RealStore always uses it and any exception thrown in such function will escalate. There are builders in Fetcher.** which can receive different fetcher functions. This is an alternative implementation to support fetchers that return values and not throw exceptions.
3a6e0d6 to
6234efc
Compare
| companion object { | ||
| fun <Key, Output> fromValueFetcher( | ||
| doFetch: (key: Key) -> Flow<Output> | ||
| ): Fetcher<Key, Output> = FlowingValueFetcher(doFetch) | ||
|
|
||
| fun <Key, Output> fromNonFlowingValueFetcher( | ||
| doFetch: suspend (key: Key) -> Output | ||
| ): Fetcher<Key, Output> = NonFlowingValueFetcher(doFetch) | ||
|
|
||
| fun <Key, Output> fromNonFlowingFetcher( | ||
| doFetch: suspend (key: Key) -> FetcherResponse<Output> | ||
| ): Fetcher<Key, Output> = NonFlowingFetcher(doFetch) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would simplify the builder indeed (taking the number of builder create function from 8 to 2 in exchange for adding 4 entry points for the fetcher). I would add some builder extension functions to make the common case easy though.
I would like to keep the fetch and transform as separate functions though. The reasons are:
- The user already needs to transform their internal library results to FetcherResult so it's no additional burden
- we can enforce that the transform is not a suspend function (it should be quick, the heavy operations should be in the fetcher)
- less code to maintain (but we can add an extension function if we want the other api back)
How about something like this?
https://gist.github.com/eyalgu/3d03420f72bc0abed76f88be111ce6d2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm i'm not sure how much we benefit from doUnwrap being explicit. It is all part of user's code so whether is a suspend or not seems unrelated (re: reason 2)? Maybe i'm not fully getting what you mean there.
In fact, i think it would be more annoyance in terms of API if they needed to provide two separate functions for something they could be just handling within their function.
digitalbuddha
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the direction this is going as it adds functionality while keeping the default case fairly simple. Whenever you have time I'd love to see this cleanup up into a real impl (no rush as this is external request)
yigit
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one thing i don't like in this CL is that we have the ResponseOrigin.Fetcher constant along with the Fetcher interface now. idk if we care though, just something that required me to change tests.
| * @param fetcher a function for fetching network records. | ||
| */ | ||
| @OptIn(ExperimentalTime::class) | ||
| @Deprecated(message = "Creating a flow from a function is deprecated, use Fetcher", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eyal@ is this the one you want to keep instead of deprecating ?
| * @param fetcher a function for fetching a flow of network records. | ||
| */ | ||
| @OptIn(ExperimentalTime::class) | ||
| @Deprecated(message = "Creating a flow from a function is deprecated, use Fetcher", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this as well. cc: @eyalgu
| * Creates a [Fetcher] from the given function. If it throws an error, the response will be | ||
| * wrapped in a [FetcherResponse.Error]. | ||
| */ | ||
| fun <Key, Output> fromNonFlowingValueFetcher( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: fromNonFlowingResponseFetcher sounds better imo
| */ | ||
| // TODO support non-throwable errors ? | ||
| class Error<T>( | ||
| val error: Throwable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the cost of supporting non throwable errors now
eyalgu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've integrated this with #123. Lets land it there or the rebase will be impossible
* Support non exception errors from fetcher * revert parital changes to store builder to reduce noise * finish off diff * Allow to create a FetcherResult.Error without a Throwable. Add tests * Add missing funcion and more tests * lint * unflake RxFlowableStoreTest * try to rename FakeFetcher to FakeRxFetcher to (maybe) solve missing codcov * move SourceOfTruth out of impl package * Rename accidental change of RxStoreBuilder.fromMaybe back to formSingle * Introduce Fetcher from #139 * fix Rx artifact * delete legacy presistor factory * fix api file * move fetcher to be a typealias * code review comments + clean up documentation * code review comments * Update store/src/main/java/com/dropbox/android/external/store4/Fetcher.kt Co-Authored-By: Yigit Boyar <[email protected]> * Revert "Update sample app's build.gradle to refer to the externally released version of Store (#159)" This reverts commit fc8da86. * update releasing.md Co-authored-by: Yigit Boyar <[email protected]>
|
@yigit can I close? |
* Support non exception errors from fetcher * revert parital changes to store builder to reduce noise * finish off diff * Allow to create a FetcherResult.Error without a Throwable. Add tests * Add missing funcion and more tests * lint * unflake RxFlowableStoreTest * try to rename FakeFetcher to FakeRxFetcher to (maybe) solve missing codcov * move SourceOfTruth out of impl package * Rename accidental change of RxStoreBuilder.fromMaybe back to formSingle * Introduce Fetcher from MobileNativeFoundation#139 * fix Rx artifact * delete legacy presistor factory * fix api file * move fetcher to be a typealias * code review comments + clean up documentation * code review comments * Update store/src/main/java/com/dropbox/android/external/store4/Fetcher.kt Co-Authored-By: Yigit Boyar <[email protected]> * Revert "Update sample app's build.gradle to refer to the externally released version of Store (MobileNativeFoundation#159)" This reverts commit fc8da86. * update releasing.md Co-authored-by: Yigit Boyar <[email protected]>
This CL changes Fetcher to be a function that returns value/error instead of
throwing. Internally, RealStore always uses it and any exception thrown in
such function will escalate.
There are builders in Fetcher.** which can receive different fetcher functions.
This is an alternative implementation to support fetchers that return values
and not throw exceptions.
Please see our contributing guidelines (contributing.md) primarily make sure to sign our cla as we cannot accept code externally without a signed cla
https://opensource.dropbox.com/cla/