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

issue edit: avoid race conditions when editing assignees, reviewers #9037

Open
wants to merge 8 commits into
base: trunk
Choose a base branch
from

Conversation

wingleung
Copy link

Continuing the work done by @mislav in #4876

Fixes #6235
Fixes #4844

Wing Leung and others added 3 commits May 2, 2024 10:03
@wingleung wingleung marked this pull request as ready for review May 4, 2024 18:45
@wingleung wingleung requested a review from a team as a code owner May 4, 2024 18:45
@wingleung wingleung requested a review from andyfeller May 4, 2024 18:45
@cliAutomation cliAutomation added the external pull request originating outside of the CLI core team label May 4, 2024
@cliAutomation cliAutomation added this to Needs review 🤔 in The GitHub CLI May 4, 2024
@andyfeller
Copy link
Contributor

@wingleung : Thank you for taking the time to contribute to the GitHub CLI and for your patience! 🙇 I'm excited to see how you picked up Mislav's work ❤️

Copy link
Contributor

@andyfeller andyfeller left a comment

Choose a reason for hiding this comment

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

Comparing these changes to #4876, I wonder what issues arose to block completion of the PR then. 🤔

@williammartin : I'd like a 2nd opinion if you wouldn't mind. I see this largely follows what @mislav was originally doing and moves to use actual user IDs than pulling assignableUsers, but would like a second opinion.

@ChrisSidebotham: given your recent interest, do you have any large organizations you can do testing with for additional feedback? 🙇

pkg/cmd/pr/edit/edit.go Outdated Show resolved Hide resolved
Comment on lines +65 to +95
if len(options.Assignees.Add) > 0 {
wg.Go(func() error {
addLogins, err := meReplacer.ReplaceSlice(options.Assignees.Add)
if err != nil {
return err
}

addIDs, err := options.Metadata.MembersToIDs(addLogins)
if err != nil {
return err
}

return addAssignees(httpClient, repo, id, addIDs)
})
}

if len(options.Assignees.Remove) > 0 {
wg.Go(func() error {
removeLogins, err := meReplacer.ReplaceSlice(options.Assignees.Remove)
if err != nil {
return err
}

removeIDs, err := options.Metadata.MembersToIDs(removeLogins)
if err != nil {
return err
}

return removeAssignees(httpClient, repo, id, removeIDs)
})
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This logic is dependent on ReplaceValue() logic removing editable content from list of content to be added, allowing it to run concurrently without having the same content being added and removed, correct?

Copy link
Author

@wingleung wingleung May 8, 2024

Choose a reason for hiding this comment

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

the ReplaceValue() is only for interaction mode, where we get a list of selected users which may contain deselected users from the default state. The selected list will be compared to the default list and reduced to have correct values in the Add and Remove fields before we do the queries.

the ReplaceValue() is not used when we run the cli with --add-assignee and --remove-assignee flags, we handle both flows in their own goroutine and let the graphql mutation handle the data change.

this could introduce an edge case where --add-assignee wingleung --remove-assignee wingleung is a race condition with 2 possible outcomes.

Alternative would be to combine multiple mutations in 1 query, which would ensure the mutations run in order ℹ️.

However, another edge case would then be --remove-assignee wingleung --add-assignee wingleung.
We don't know the order of which the flags were given, so if we always do the addAssigneesToAssignable first and then the removeAssigneesFromAssignable then the last flag in our edge case will not do it's job.

I'm overthinking it, the user of the cli is responsible of using correct flag values, --add-assignee wingleung --remove-assignee wingleung is prolly not a real life use case. And afterwards we just need to pass it on to graphql as fast as we can 😄

pkg/cmd/pr/shared/editable.go Outdated Show resolved Hide resolved
@ChrisSidebotham
Copy link

@andyfeller - I would be happy to test this with the Azure org which is where we noticed the orignal issue

@andyfeller
Copy link
Contributor

@andyfeller - I would be happy to test this with the Azure org which is where we noticed the orignal issue

@ChrisSidebotham : many thanks! because of the nuanced nature of scale to test against, I want to make sure you, @wzshiming, @jtracey93 can weigh in on the development build solving the issue.

Just a reminder, you can build a given cli/cli PR via:

gh pr checkout 9037
make
bin/gh ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
external pull request originating outside of the CLI core team
Projects
No open projects
The GitHub CLI
  
Needs review 🤔
4 participants