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

Detach commit statuses from pull requests #7163

Merged
merged 70 commits into from Mar 29, 2019
Merged

Detach commit statuses from pull requests #7163

merged 70 commits into from Mar 29, 2019

Conversation

niik
Copy link
Member

@niik niik commented Mar 26, 2019

Overview

References #6982

2019-03-25 18-09-13 2019-03-25 18_10_10

Description

This is the second step in a series of PRs to address how the app retrieves, stores, and presents pull requests (see previous work).

This PR removes the direct relationship between pull requests and commit statuses. Prior to this change all pull requests in the app had a commit status attached to them and when we loaded the list of PRs we used the SHA provided in the PR details from the API to look up the commit status. This meant, among other things, that the commit status would not refresh until we refreshed the list of PRs (so that we got the latest SHA). With this decoupling we are now asking the API for the latest commit status by querying the named ref (i.e refs/pulls/123/head) instead of providing an explicit SHA such that we're always getting the commit status for the most recent commit of any particular PR.

This decoupling also means that we no longer have to wait for the commit statuses to load in order to show the list of open PRs, this significantly cuts down on the time it takes to display the PR list from a cold cache.

The approach I've taken here is not one that we've used a whole lot in the past but I think the advantages it provides are more than sufficient to merit it. I've introduced a new store; the CommitStatusStore. Through this store consumers are able to subscribe to a particular ref (can be a named ref or a SHA) and receive updates for that ref until they choose to unsubscribe. This means that the CIStatus component is able to subscribe directly to the store when it's mounted (and unsubscribe when it's unmounted) meaning that we'll now load statuses on-demand as the component appears on screen (with overrun/underrun provided by our list component meaning that it'll load a few statuses before they're scrolled to. This works really well as we're not relying on commit statuses for any application logic, only presentation. Should that change the store can be expanded to provide an awaitable resource to get the latest status for any given ref.

The store will run up to 5 concurrent fetches of status from the API (compared to the previous implementation which did one status at a time serially) which greatly improves performance and minimizes effects of any single status fetch taking a long time to get. The concurrency management is handled by an external library, p-limit but in addition to that the store will re-use handle multiple subscriptions to the same ref and ensure that only one fetch is run for each. Additionally the store handles unsubscriptions from a ref during refresh such that switching a repository will stop refreshing refs that are no longer subscribed to. A ref will be fetched at most once a minute but there's a three-minute interval timer that runs while the app is focused and the store will also refresh when the app regains focus.

Statuses are cached in memory (I've removed the database table that was used when statuses were tied to PRs) in a least recently used cache (quick-lru) to prevent unbounded memory growth.

PR loading screen

Prior to this PR we had a facade "skeleton" loading screen for PRs. That pattern only existed in this particular view and rather than investing time making that compatible with the new store I've switched over to a loading view more in line with what all our other loading lists do (such as the cloneable repository list).

Notes for testing / backwards incompatibility

This PR deletes a table from the pullRequestsDatabase making it incompatible with prior versions of GitHub Desktop. As such, after running this branch you need to manually delete the PR database to have it recreated again before you can use PRs in development or other branches. Do this by opening DevTools, clicking on the Applications tab, locating the PullRequestsDatabase under the IndexedDB group in the sidebar and click Delete database

image

Release notes

Notes: [Improved] Pull requests load faster and PR build status updates automatically.

niik added 30 commits March 11, 2019 11:36
Replace custom concurrent promise map function with p-limit
That return should have been a continue
This works for both contributor and owner PRs and lets us completely decouple build status from the PR data since we no longer need an updated SHA in order to request the most recent build status
@niik niik added the ready-for-review Pull Requests that are ready to be reviewed by the maintainers label Mar 26, 2019
@tierninho
Copy link
Contributor

Tested and overall functions well. Super fast and responsive.

  • spotted this, which seemed to happen organically
    image
  • Is this part of this PR? I was wondering if any testing needs to be done around this (if it's new)? skipping fast-forward for all branches as there are 21 local branches - this will run again when there are less than 20 local branches tracking remotes

@niik
Copy link
Member Author

niik commented Mar 27, 2019

Tested and overall functions well. Super fast and responsive.

💖

  • spotted this, which seemed to happen organically

While not related to this PR that's an interesting error and I've opened #7169 with more context about that.

That error is actually thrown by fetchCommit which is used to retrieve user information for a particular commit in order to display the correct name and avatar.

  • Is this part of this PR? I was wondering if any testing needs to be done around this (if it's new)?

It's not new nor part of this PR. It was introduced in #4447.

@shiftkey
Copy link
Member

shiftkey commented Mar 27, 2019

I wanted to write up this interesting case I stumbled upon - just wanted to flag this in case it's intentional.

Here's what I did:

I was hoping that the cached values would be shown here, but it looks like - because the network requests failed while trying to refresh the list - the previous values are cleared from the list:

There's mention in the PR about an LRU cache in-memory rather than using IndexedDB, which is fine, but I'll dig into this as part of the PR to see if I can find the specific change related to this behaviour...

Copy link
Member

@shiftkey shiftkey left a comment

Choose a reason for hiding this comment

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

These changes look great, and it's very cool to see us be able to clean up a bunch of code that's no longer needed now we've simplified this area.

After a bunch of testing most of the feedback I have is on minor stuff, happy to discuss what's worth punting or deferring...

app/src/lib/stores/commit-status-store.ts Outdated Show resolved Hide resolved
app/src/lib/stores/commit-status-store.ts Outdated Show resolved Hide resolved
app/src/lib/stores/commit-status-store.ts Outdated Show resolved Hide resolved
app/src/lib/stores/commit-status-store.ts Outdated Show resolved Hide resolved
app/src/lib/stores/commit-status-store.ts Outdated Show resolved Hide resolved
app/src/lib/stores/commit-status-store.ts Outdated Show resolved Hide resolved
niik and others added 5 commits March 28, 2019 10:45
Co-Authored-By: Brendan Forster <github@brendanforster.com>
Co-Authored-By: Brendan Forster <github@brendanforster.com>
Co-Authored-By: Brendan Forster <github@brendanforster.com>
Commit status retrieval is not a critical function of the app and we could end up logging a whole lot of errors when the machine is without internet.
Co-Authored-By: niik <j.markus.olsson@gmail.com>
@niik niik mentioned this pull request Mar 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-for-review Pull Requests that are ready to be reviewed by the maintainers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants