Skip to content
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

fix: prevent extra initial calls to search endpoints #9782

Merged
merged 4 commits into from
Aug 7, 2024

Conversation

ashtonG
Copy link
Contributor

@ashtonG ashtonG commented Aug 1, 2024

Ticket

ET-677

Description

this fixes an issue where the new table experience tables would call their search endpoints multiple times on mount, possibly causing server load issues. This happened due to two root causes:

  1. the comparison view would call the search endpoint for user selections even when the comparison view was closed and the user had selected no experiments or runs. we now bail on the request if the comparison view is closed or the selection is empty. This may impact the user because now the comparison view will update on open instead of in the background, but I think this is a fair tradeoff.

  2. the sort state updated as an effect of loading the settings, so the polling function would initially fire when the settings loaded, then again when the sort state updated. We now derive the sort state directly from the sort string instead directly update the sort state when the settings load.

Test Plan

  • with developer tools open to the network tab, visit a project's run list
  • in the request list, every call to the runs endpoint should be 5 seconds apart
  • when opening the comparison view, another call should be made
  • Repeat the above for the searches view as well as the New Experiment List page

Checklist

  • Changes have been manually QA'd
  • New features have been approved by the corresponding PM
  • User-facing API changes have the "User-facing API Change" label
  • Release notes have been added as a separate file under docs/release-notes/
    See Release Note for details.
  • Licenses have been included for new code which was copied and/or modified from any external code

this fixes an issue where the new table experience tables would call
their search endpoints multiple times on mount, possibly causing server
load issues. This happened due to two root causes:

1) the comparison view would call the search endpoint for user
selections even when the comparison view was closed and the user had
selected no experiments or runs. we now bail on the request if the
comparison view is closed or the selection is empty. This may impact the
user because now the comparison view will update on open instead of in
the background, but I think this is a fair tradeoff.

2) the sort state updated as an effect of loading the settings, so the
polling function would initially fire when the settings loaded, then
again when the sort state updated. We now derive the sort state directly
from the sort string instead.
@ashtonG ashtonG requested a review from a team as a code owner August 1, 2024 20:05
@cla-bot cla-bot bot added the cla-signed label Aug 1, 2024
Copy link

netlify bot commented Aug 1, 2024

Deploy Preview for determined-ui ready!

Name Link
🔨 Latest commit da49c1f
🔍 Latest deploy log https://app.netlify.com/sites/determined-ui/deploys/66b29148c94b9d00073afb6f
😎 Deploy Preview https://deploy-preview-9782--determined-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

codecov bot commented Aug 1, 2024

Codecov Report

Attention: Patch coverage is 61.45833% with 37 lines in your changes missing coverage. Please review.

Project coverage is 49.73%. Comparing base (15226b7) to head (da49c1f).
Report is 21 commits behind head on main.

Files Patch % Lines
webui/react/src/pages/FlatRuns/FlatRuns.tsx 5.55% 17 Missing ⚠️
...bui/react/src/pages/F_ExpList/F_ExperimentList.tsx 0.00% 16 Missing ⚠️
webui/react/src/components/ComparisonView.tsx 90.90% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9782      +/-   ##
==========================================
- Coverage   54.05%   49.73%   -4.32%     
==========================================
  Files        1260      937     -323     
  Lines      155545   126227   -29318     
  Branches     3503     3508       +5     
==========================================
- Hits        84074    62783   -21291     
+ Misses      71325    63298    -8027     
  Partials      146      146              
Flag Coverage Δ
harness ?
web 53.23% <61.45%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
webui/react/src/components/Searches/Searches.tsx 56.90% <100.00%> (+0.34%) ⬆️
webui/react/src/hooks/useDebouncedSettings.ts 100.00% <100.00%> (ø)
webui/react/src/components/ComparisonView.tsx 91.73% <90.90%> (+1.03%) ⬆️
...bui/react/src/pages/F_ExpList/F_ExperimentList.tsx 0.00% <0.00%> (ø)
webui/react/src/pages/FlatRuns/FlatRuns.tsx 11.06% <5.55%> (-0.04%) ⬇️

... and 323 files with indirect coverage changes

@keita-determined
Copy link
Contributor

@EmilyBonar could you also review this since i think you are more familiar with the code

@keita-determined
Copy link
Contributor

in the request list, every call to the runs endpoint should be 5 seconds apart

i tested it against gcloud server, and see multiple run apis. that's not what we expect, right?

Screen.Recording.2024-08-01.at.2.55.43.PM.mov

@ashtonG
Copy link
Contributor Author

ashtonG commented Aug 2, 2024

with the comparison view open i'd expect to see two -- one for the main list and one for the selection for comparison view.

i also noticed an issue where users aren't able to add new sorts. looking into these now.

@@ -31,7 +31,7 @@ export function useDebouncedSettings<T extends t.HasProps | t.ExactC<t.HasProps>
const settingsObs = useMemo(() => userSettings.get(type, path), [type, path]);
const [localState, updateLocalState] = useState<Loadable<T | null>>(NotLoaded);

useEffect(() => {
useLayoutEffect(() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw issues where we were still seeing two requests to the search endpoint because settings was loaded but column widths were not. useObservable subscribes to the observable in useLayoutEffect instead of useEffect, so we do that here to ensure all the subscriptions fire at the same time.

@ashtonG ashtonG self-assigned this Aug 5, 2024
@ashtonG ashtonG added the to-cherry-pick Pull requests that need to be cherry-picked into the current release label Aug 5, 2024
Copy link
Contributor

@EmilyBonar EmilyBonar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, can confirm that I'm not seeing the repeated initial calls in the network tab!

Comment on lines 75 to 78
if (response?.pagination?.total && response?.pagination?.total > SELECTION_LIMIT) {
setIsSelectionLimitReached(true);
} else {
setIsSelectionLimitReached(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could be reduced to setIsSelectionLimitReached(response?.pagination?.total && response?.pagination?.total > SELECTION_LIMIT);

Comment on lines 107 to 110
if (response?.pagination?.total && response?.pagination?.total > SELECTION_LIMIT) {
setIsSelectionLimitReached(true);
} else {
setIsSelectionLimitReached(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: same reduction

}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoadingSettings]);
useLayoutEffect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sugg: we're doing this same pattern 3 times, could it be extracted out into a custom hook?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure if there's value in abstracting this pattern -- while we do handoff local/server state three times in this pr (and more when you factor in filterFormState + columnWidths), the knobs necessary to twist (observable, default value, state, etc.) mean that it'll either only be used in these three places or it'll be easier to just inline.

Comment on lines +308 to +310
let cleanup: () => void;
// eslint-disable-next-line prefer-const
cleanup = eagerSubscribe(projectSettingsObs, (ps, prevPs) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: what's the reason for declaring the variable separately from initializing it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ran into an issue where cleanup wasn't defined in scope when the module was parsed. when we used this pattern for filterformstate, cleanup was defined and set at runtime, so i think it's just an odd issue. I'm going to take another look and see if it still makes sense.

@ashtonG ashtonG merged commit 9702d22 into main Aug 7, 2024
82 of 95 checks passed
@ashtonG ashtonG deleted the bug/multiple-search-calls branch August 7, 2024 14:47
github-actions bot pushed a commit that referenced this pull request Aug 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed to-cherry-pick Pull requests that need to be cherry-picked into the current release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants