Skip to content

Conversation

@yigit
Copy link
Collaborator

@yigit yigit commented Mar 23, 2020

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/

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.
Comment on lines 12 to 25
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)
}
}
Copy link
Contributor

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:

  1. The user already needs to transform their internal library results to FetcherResult so it's no additional burden
  2. we can enforce that the transform is not a suspend function (it should be quick, the heavy operations should be in the fetcher)
  3. 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

Copy link
Contributor

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

Copy link
Collaborator Author

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.

Copy link
Contributor

@digitalbuddha digitalbuddha left a 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)

Copy link
Collaborator Author

@yigit yigit left a 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",
Copy link
Collaborator Author

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",
Copy link
Collaborator Author

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(
Copy link
Contributor

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
Copy link
Contributor

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 added a commit that referenced this pull request Apr 21, 2020
Copy link
Contributor

@eyalgu eyalgu left a 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

@eyalgu eyalgu linked an issue Apr 29, 2020 that may be closed by this pull request
eyalgu added a commit that referenced this pull request Apr 29, 2020
* 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]>
@eyalgu
Copy link
Contributor

eyalgu commented May 4, 2020

@yigit can I close?

@yigit yigit closed this May 5, 2020
itsandreramon pushed a commit to itsandreramon/Store that referenced this pull request Feb 26, 2025
* 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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants