Skip to content

Conversation

@crazy-max
Copy link
Member

@crazy-max crazy-max commented Mar 31, 2023

fixes #4145
related to #4142 (comment)

- What I did

Spawning a goroutine for each iteration in the loop when listing plugins is racy unfortunately. plugins slice is protected with a mutex so not sure why it fails.

I tried using a channel to collect the plugins instead of a slice to guarantee that they will be appended to the list in the order they are processed but no dice.

I also tried without errgroup package and simply use sync.WaitGroup but same. I have also created an extra channel to receive errors from the goroutines but racy too.

I think the change in this function is not related to the race condition but newPlugin func is.

- How I did it

Reverts commit 62f2358.

- How to verify it

Run repro from #4145

- Description for the changelog

- A picture of a cute animal (not mandatory but encouraged)

This reverts commit 62f2358.

Spawning a goroutine for each iteration in the loop when listing
plugins is racy unfortunately. `plugins` slice is protected with
a mutex so not sure why it fails.

I tried using a channel to collect the plugins instead of a slice
to guarantee that they will be appended to the list in the order
they are processed but no dice.

I also tried without errgroup package and simply use sync.WaitGroup
but same. I have also created an extra channel to receive errors
from the goroutines but racy too.

I think the change in this function is not related to the race
condition but newPlugin is. So revert in the meantime :(

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
@crazy-max
Copy link
Member Author

crazy-max commented Mar 31, 2023

Performance improvements from #4129 do not have an impact with this commit. See updated bench result: https://github.com/crazy-max/docker-cli-bench/blob/c53a2c6eb9216af09034205d156c78c222f2db73/bench.md

@cpuguy83
Copy link
Collaborator

Looks like its racing because cmd.Commands() modifies cmd

Wrote a test case for this (sort of...) and it looks like its racing because cmd.Commands() is modifying cmd.
Possibily caching Commands() in the main goroutine will fix the issue.... though newPlugin will need to be modified to take a []string instead.

func (c *Command) Commands() []*Command {
	// do not sort commands if it already sorted or sorting was disabled
	if EnableCommandSorting && !c.commandsAreSorted {
		sort.Sort(commandSorterByName(c.commands))
		c.commandsAreSorted = true
	}
	return c.commands
}

@crazy-max
Copy link
Member Author

Looks like its racing because cmd.Commands() modifies cmd

Thanks @cpuguy83 I was just saying that to @thaJeztah on Slack earlier, should have put that in the PR description 🙈

thaJeztah: Thank you! Do we understand what exactly causes the issue? (Would there be ways to work around it?)

Me: I think it could be related to newPlugin being racy. Didn't dig deep about why but that's my best bet. Probably when iterating cobra commands:

for _, cmd := range rootcmd.Commands() {


Wrote a test case for this (sort of...) and it looks like its racing because cmd.Commands() is modifying cmd.
Possibily caching Commands() in the main goroutine will fix the issue.... though newPlugin will need to be modified to take a []string instead.

I will take another look thx

@thaJeztah
Copy link
Member

@crazy-max do @cpuguy83 you want to include changes in this PR, or as a follow-up? I'm considering doing a new build of 24.0.0-beta.1 , and we could consider merging this PR (revert of that commit), then work on the alternative

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM (if we're okay with doing this as first step)

@crazy-max
Copy link
Member Author

I'm fine for a follow-up 👍

@cpuguy83 cpuguy83 merged commit dcb6a0d into docker:master Mar 31, 2023
@crazy-max crazy-max deleted the fix-racy-help branch March 31, 2023 19:37
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.

Help command is racy

3 participants