-
-
Notifications
You must be signed in to change notification settings - Fork 822
Description
Is your feature request related to a problem? Please describe.
When using LocalResource, it's not clear what the sequencing and cancellation behavior is. For example, what happens if one of the dependencies changes faster than the future completes? What if my async fetcher function has side effects?
For example:
async fn a_slow_fetch_operation(ms: u64) -> u64 {
tokio::time::sleep(Duration::from_millis(ms));
ms / 2
}
let some_signal = RwSignal::new(10_000);
let res = LocalResource::new(|| async {
let some_value = a_slow_fetch_operation(some_signal.get()).await;
store_in_local_storage(some_value);
});
some_signal.set(100);Here, the second fetch will obviously complete before the first fetch. What I need to know is:
- What values will the
LocalResource.get()take? Will it go straight fromNonetoSome(50), or will the second fetch be delayed until the first one completes? Is there a risk of it going backwards fromSome(50)toSome(5000)? - What about the side-effects? Could the local-storage value transition from
50to5000?- Obviously there's no way for
LocalResourceto guarantee that intermediate side effects of the fetch operation don't get called, what I'm most concerned about isLocalResourcemaking guarantees about stopping async processing of one request before starting the next; that is, guaranteeing that no new side-effects will happen after the next effect starts.
- Obviously there's no way for
Describe the solution you'd like
I would like the documentation for LocalResource to give a clearer description of how it handles cancellation when signal dependencies change, and to explicitly specify any guarantees it makes about when it will start/stop processing one fetch call relative to other fetch calls.
Describe alternatives you've considered
If LocalResource makes guarantees about the state ordering of its .get() return value, but not about cancelling pending fetch functions, I guess I could use and Effect to handle side effects:
let res = LocalResource::new(|| async {
a_slow_fetch_operation(some_signal.get()).await
});
Effect::new(move || {
if let Some(some_value) = res.get() {
store_in_local_storage(some_value);
}
});