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

feat: Connect ProjectStore with streaming updates #8834

Merged
merged 31 commits into from
Mar 6, 2024

Conversation

gt2345
Copy link
Contributor

@gt2345 gt2345 commented Feb 13, 2024

Description

Connects workspace details page to ProjectStore, and ProjectStore monitors projects changes through streaming updates after the initial fetch.

Test Plan

  • Navigate to workspace details page, Inspect -> Network -> WS and there should be a webSocket for "/stream"
  • Sorting should work as expected
  • Change the name or archive a project, the change should be reflected very quickly and note that there is no API call
  • Open 2 browsers with 2 different workspace detail page, move project from one workspace to another, the project should move as expected and there should be no API call

Commentary (optional)

Note that if viewing as list, the changes of description is not immediately reflected due to how the Input is setup.

Checklist

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

Ticket

MD-265

@cla-bot cla-bot bot added the cla-signed label Feb 13, 2024
Copy link

netlify bot commented Feb 13, 2024

Deploy Preview for determined-ui ready!

Name Link
🔨 Latest commit b9a4716
🔍 Latest deploy log https://app.netlify.com/sites/determined-ui/deploys/65e79734912c7200085ba945
😎 Deploy Preview https://deploy-preview-8834--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.

Comment on lines 12 to 18
func bypasscheckorigin(r *http.Request) bool {
return true
}

var upgrader = websocket.Upgrader{
CheckOrigin: bypasscheckorigin,
}
Copy link
Member

Choose a reason for hiding this comment

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

I didn't know about this header.

This is a fine solution for this draft PR but we'll need to fix the server to handle this better in the near future.

Comment on lines 90 to 94
let same = true;
forEach(entity, (val, k) => {
if (!this.#curEntity?.[k as Streamable].spec.equals(val.spec)) same = false;
});
return same;
Copy link
Member

Choose a reason for hiding this comment

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

This feels like a case for Array.prototype.every(), for the early exit behavior:

return Object.entries(entity).every(
    ([k, val]) => this.#curEntity![k as Streamable].spec.equals(val.spec)
)

Wait, but even then... this isn't quite right, because you really need to compare two sparse dictionaries.

If your curEntity was:

{ 
  projects: pspec1
  trials: tspec1
}

and your entity was:

{
  projects: pspec1
}

then this check would say "true" because it checks that all keys in entity match the same keys on curEntity, but it doesn't check for extra keys in curEntity.

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 named the function poorly, but the intention was that, if I'm currently monitoring

{ 
  projects: pspec1
  trials: tspec1
}

and I subscribe to

{
  projects: pspec1
}

then I should skip sending the subscription to the stream because what I want for projects has not changed. Thinking about this, I wonder if backend can do something similar, suppose we want to keep the fact that there is only one live subscription, can backend parse new subscription and only make changes if necessary?
For example, given the current subscription being

{ 
 projects: pspec1
 trials: tspec1
}

when receiving a new subscription

{ 
 projects: pspec2
 trials: tspec1
}

can we only make changes to projects, and keep everything trials untouched?

Copy link
Member

Choose a reason for hiding this comment

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

can backend parse new subscription and only make changes if necessary?

No. That was the initial design, and it was way too hard to implement.

Plus, the option to allow that design created some extremely confusing corner cases in the client, like if:

  • client starts subscribed to trials 1 and 2
  • client receives offline messages until seqno S1
  • client resubscribes to just trial 1
  • server sees update for trial 2 with seqno S2
  • server sees update for trial 1 with seqno S3
  • client sees update to trial 1 with seqno S3, saves S3 as max_seqno
  • client resubscribes to trials 1 and 2, listing both 1 and 2 as known entities and report max_seqno as S3. This is a problem because with 1 and 2 in known and max_seqno of S3, trial 2's update with seqno S2 will never be sent.

But I do think that having multiple independent subscriptions (each one immutable) is a simple and effective alternative for solving this problem; that's why I made a ticket for that.

Copy link
Contributor Author

@gt2345 gt2345 Feb 14, 2024

Choose a reason for hiding this comment

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

Can we make KeyCache sync with the current subscription on client side? So when client resubscribes to just trial 1 (unsubscribe from trial 2), the client remove trial 2 from keyCache (either generating a new keyCache, or passively processing trials_deleted), and when client resubscribes to trials 1 and 2, trial 2 should not be listed as known

Copy link
Member

@rb-determined-ai rb-determined-ai left a comment

Choose a reason for hiding this comment

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

Hey, this looks pretty good. It would be really nice to see some unit tests in there too.

That caused me to see if I wrote unit tests for mine, and it looks like I did, and it also looks like I forgot to git add them. But that's fixed now, if you want to see my unit tests.

But I think unit tests are going to be very important to keeping this streaming updates part of our system bug free, much more so than with the REST API.

Copy link

codecov bot commented Feb 16, 2024

Codecov Report

Attention: Patch coverage is 82.78336% with 120 lines in your changes are missing coverage. Please review.

Project coverage is 47.52%. Comparing base (6ecd81e) to head (b9a4716).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8834      +/-   ##
==========================================
+ Coverage   47.35%   47.52%   +0.17%     
==========================================
  Files        1162     1168       +6     
  Lines      176133   176705     +572     
  Branches     2237     2354     +117     
==========================================
+ Hits        83402    83975     +573     
+ Misses      92573    92572       -1     
  Partials      158      158              
Flag Coverage Δ
backend 42.63% <0.00%> (-0.02%) ⬇️
harness 63.94% <ø> (-0.01%) ⬇️
web 42.89% <83.14%> (+0.35%) ⬆️

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

Files Coverage Δ
webui/react/src/services/stream/index.ts 100.00% <100.00%> (ø)
webui/react/src/types.ts 100.00% <100.00%> (ø)
master/internal/core.go 2.18% <0.00%> (ø)
webui/react/src/pages/ProjectDetails.tsx 0.00% <0.00%> (ø)
webui/react/src/services/decoder.ts 23.24% <0.00%> (+0.08%) ⬆️
master/internal/api/handler.go 0.00% <0.00%> (ø)
webui/react/src/components/ExperimentMoveModal.tsx 66.36% <50.00%> (-0.15%) ⬇️
webui/react/src/services/stream/projects.ts 94.11% <94.11%> (ø)
webui/react/src/services/stream/stream.ts 99.17% <99.17%> (ø)
webui/react/src/services/stream/keyCache.ts 95.34% <95.34%> (ø)
... and 6 more

... and 5 files with indirect coverage changes

@gt2345 gt2345 merged commit e1ca242 into main Mar 6, 2024
70 of 83 checks passed
@gt2345 gt2345 deleted the gt/ts-streaming-client-1 branch March 6, 2024 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants