Conversation
WD-33878
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||
d1a47dc to
d9de123
Compare
| } | ||
|
|
||
| // This load is the latest one to complete successfully. | ||
| if (loadId >= latestSuccessfulLoad) { |
There was a problem hiding this comment.
Would we ever care about the response if it's not the very latest call? If not could it abort the other calls that are in progress?
Or another way to look at this might be: do we ever want to allow another call to be initiated if there's already a fetch in progress?
There was a problem hiding this comment.
We mightn't care about the data that's returned, which is why this check is here. This lets us temporarily use data from an old request whilst waiting for the result of a newer request.
The initiator of the load can also pass an AbortSignal to the load function, so they're capable of cancelling their own requests if something superseding it comes in. I don't think it makes much sense for the load to automatically be cancelled if a new one starts, as the thing that triggers a new load has full control over the previous load too.
See https://github.com/canonical/juju-dashboard/pull/2237/changes#diff-c68dd5398fe4e6af6d1b13b0273295f7979c5d6ffc4fbb1d17cc3af184f5ba92R103 for an example.
There was a problem hiding this comment.
If we've already requested the data is there any need for another call to be made? For example, if we had three components on the page that all needed the same data, so on load they're all going to fire a request for the data and we'd hit the API three times.
Do you see an issue with preventing the second and third requests from firing if the source is already loading?
There was a problem hiding this comment.
We may want to trigger a new request when there's already one pending.
For example, we have a request pending to list models. While it's loading, we create a new model. In this case, we'd immediately want to start loading a fresh list of models, as the original one could return an outdated result.
It's worth noting that the only way to "trigger a load" from the app is via the invalidate method, but this method doesn't directly trigger the load request (ie. spamming invalidate from a component will not spin up a heap of loads). Instead, invalidate just notifies the source implementation that it should try update the data.
Therefore, this pattern places all of the control into the source implementation. The source is orchestrate concurrent loads as it sees fit, this source base just does the bookkeeping.
There was a problem hiding this comment.
Ah OK, that makes sense. Thanks!
| }) | ||
| .finally(() => { | ||
| // Track the latest load to complete, favouring the latest one. | ||
| latestCompletedLoad = Math.max(loadId, latestCompletedLoad); |
There was a problem hiding this comment.
I think this needs to check if it was aborted as this will always run so an abort would cause this to update the id (if I've read this correctly).
There was a problem hiding this comment.
You've read it correctly, however we do want to track whenever a load finishes, whether it finishes successfully or not. That's why latestCompletedLoad is tracked in the finally, whilst the latestSuccessfulLoad is only tracked in the then branch.
WD-33879
| } | ||
|
|
||
| // This load is the latest one to complete successfully. | ||
| if (loadId >= latestSuccessfulLoad) { |
There was a problem hiding this comment.
If we've already requested the data is there any need for another call to be made? For example, if we had three components on the page that all needed the same data, so on load they're all going to fire a request for the data and we'd hit the API three times.
Do you see an issue with preventing the second and third requests from firing if the source is already loading?
Done
Source<T>definition (WD-33878)createSource<T>to handle basic source house keeping (WD-33879)