Skip to content

prevent concurrent fetches between user and status indicator checks#6141

Merged
shiftkey merged 7 commits intodevelopmentfrom
use-the-flag-to-detect-network-issues
Jan 26, 2019
Merged

prevent concurrent fetches between user and status indicator checks#6141
shiftkey merged 7 commits intodevelopmentfrom
use-the-flag-to-detect-network-issues

Conversation

@shiftkey
Copy link
Member

@shiftkey shiftkey commented Nov 9, 2018

Overview

This PR does some tidy up around how our background fetching from #4770 integrates with other operations and hopefully resolves these reported issues:

Fixes #6121
Fixes #5438
Fixes #5328

Description

When we initially rolled out #4770 the goal was to be able to fetch in the background without the user knowing (or needing to care about errors). That's why we originally went through GitStore to perform the fetch - but this avoided withPushPull which checks and prevents concurrent push/pull/fetch operations.

This seemed fine for the most part, but I believe this has left us open to a race condition with concurrent fetches, where the user starts a fetch at the same time as the repository indicator updater is fetching the same repository, or vice versa.

I stumbled across microsoft/vscode#47141 earlier today where VSCode basically outlined this behaviour between itself and an extension, and this comment comes to the same conclusion about what I believe is happening to these users:

This issue occurs when git-radar is doing a fetch in background and user runs git fetch/pull. Git has index.lock to lock index during a fetch, so you cannot corrupt the index by doing concurrent fetches. Your git command fails because of this lock prevents git modifying index.

michaeldfallen/git-radar#81 (comment)

It's hard to see from the reported issues which Git operation was the one that failed, but I believe it can be tripped with just a fetch (pull also performs a fetch to update it's refs, I'm not sure about push from memory).

What can we do here? I think the simplest answer is to push these status indicator updates through our existing infrastructure - these use repository state to control whether or not an operation should be performed.

The worst case scenarios I can think of about this change:

  • user tries to fetch/push/pull while the status indicator update is in progress - the button will now show details about the status indicator update (it did not before)
  • status indicator update tries to run while user is fetch/push/pull - status indicator update is skipped

Release notes

Notes: Prevent concurrent fetches corrupting Git index by adding checking to repository indicator updates

this.updateMenuItemLabels(repository)
this._initializeCompare(repository)
this.refreshIndicatorsForRepositories([repository])
this.refreshIndicatorsForRepositories([repository], false)

This comment was marked as spam.

@billygriffin
Copy link
Contributor

billygriffin commented Nov 9, 2018

This seems like a step in the right direction here.

status indicator update tries to run while user is fetch/push/pull - status indicator update is skipped

This seems like expected behavior as a user. My hierarchy of things I care about is definitely whatever is happening in Push/Pull first, much more so than the background ops of repo indicators - it's fine for them to update during the next background operation.

user tries to fetch/push/pull while the status indicator update is in progress - the button will now show details about the status indicator update (it did not before)

I'm not positive I understand what you mean by this. What will the button show differently? Does it interfere with the fetch/push/pull op?

More generally, I think you're aligned with this, but since this has been an issue since 1.3, I think it's ok to release in 1.6 or 1.5.1 from a prioritization perspective.

@shiftkey
Copy link
Member Author

shiftkey commented Nov 9, 2018

@billygriffin yeah, this isn't something I planned to pull in for 1.5.0 - I just wanted to open this PR early so I can work through the impact (race conditions are great)!

@shiftkey
Copy link
Member Author

shiftkey commented Nov 9, 2018

I'm not positive I understand what you mean by this. What will the button show differently? Does it interfere with the fetch/push/pull op?

@billygriffin our normal fetch/push/pull flow will take the progress reported by Git and display it in the toolbar button. We do this for two reasons:

  • it's nice to show users that progress, especially when it takes a while to complete
  • if a fetch/push/pull is in progress, we disable the button so the user doesn't start a second operation

It's that second point that I believe is relevant here, because of how the app can arbitrarily run a fetch in the background (with no feedback to the user). If we don't check for an in-flight fetch/push/pull operation in the background, and the fetch can take a while due to slow network or complex repositories, the likelihood of concurrent fetches increases significant.

@shiftkey shiftkey changed the title [WIP] prevent concurrent fetches between user and status indicator checks prevent concurrent fetches between user and status indicator checks Nov 9, 2018
@shiftkey shiftkey changed the title prevent concurrent fetches between user and status indicator checks [WIP] prevent concurrent fetches between user and status indicator checks Nov 23, 2018
@shiftkey shiftkey changed the title [WIP] prevent concurrent fetches between user and status indicator checks prevent concurrent fetches between user and status indicator checks Dec 17, 2018
@shiftkey shiftkey added the ready-for-review Pull Requests that are ready to be reviewed by the maintainers label Dec 17, 2018
@outofambit outofambit changed the base branch from master to development December 27, 2018 21:47
@shiftkey shiftkey added this to the 1.6.1 milestone Jan 8, 2019
@shiftkey
Copy link
Member Author

shiftkey commented Jan 8, 2019

Tentatively scheduling this for 1.6.1 because I'd like it to sit on beta for some time to verify the underlying issues are resolved.

@shiftkey shiftkey added the time-sensitive Pull Requests where reviews need to happen in a timely manner label Jan 18, 2019
@shiftkey
Copy link
Member Author

Marking this one as time-sensitive as I'd like to get a first round of review and see how we feel about getting this into 1.6.1 because of the priority-2 issues associated with it.

@outofambit outofambit self-requested a review January 18, 2019 17:03
Copy link
Contributor

@outofambit outofambit left a comment

Choose a reason for hiding this comment

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

This seems like a reasonable next step to me. I'm still wrapping my head around some of the related internal logic outside of the PR, but general 👍 from me

@outofambit
Copy link
Contributor

anyone else from @desktop/engineering want to weigh in?

@tierninho
Copy link
Contributor

@shiftkey Any specific that needs to be tested here? I am not sure how to simultaneously trigger two or more of the outlined actions.

@shiftkey
Copy link
Member Author

shiftkey commented Jan 22, 2019

@tierninho it's kind of tricky because the background fetch doesn't really have any UI, and you'll see this message after it's completed:

log.info(
`Background fetch for ${
repositories.length
} repositories took ${timeInSeconds}sec`
)

This also forces the background fetcher through AppStore.shouldBackgroundFetch, which means it's more likely to hit the 30min minimum interval for background fetching and not fetch.

if (timeSinceFetch < BackgroundFetchMinimumInterval) {
const timeInSeconds = Math.floor(timeSinceFetch / 1000)
log.debug(
`Skipping background fetch as '${repoName}' was fetched ${timeInSeconds}s ago`
)
return false
}

Maybe just trying to fetch regularly in the app to see if you can force the background fetcher to trip at the same time as your manual fetch?

@iAmWillShepherd iAmWillShepherd self-assigned this Jan 25, 2019
@shiftkey
Copy link
Member Author

Merging this in so that it's available as part of the first beta

@shiftkey shiftkey removed the time-sensitive Pull Requests where reviews need to happen in a timely manner label Jan 26, 2019
@shiftkey shiftkey merged commit 309806c into development Jan 26, 2019
@shiftkey shiftkey deleted the use-the-flag-to-detect-network-issues branch January 26, 2019 21:52
@sanjaygupta1011
Copy link

You need to update the reference using following Git command on Git bash:
$ git update-ref -d refs/remotes/origin/[locked branch name]
then pull using $git pull

[locked branch name] is the name of the branch that the error is happening because of mismatch of commit Ids.

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

6 participants