plugin/localbinary: Exit output stream goroutines when plugin closes

This commit ensures that when a plugin instance is closed the goroutines
responsible for streaming stdout and stderr of the called binary will
also exit, preventing a goroutines leak.

Before this commit these goroutines could stay blocked forever if
Close() was called while the binary still had some pending output.

I found this bug after debugging a real world goroutine leak, the
goroutines dump would show thousands of goroutines at:

```
github.com/tsuru/tsuru/vendor/github.com/docker/machine/libmachine/drivers/plugin/localbinary.stream(0xc023013d80, 0xc0000aad20)
	/home/travis/gopath/src/github.com/tsuru/tsuru/vendor/github.com/docker/machine/libmachine/drivers/plugin/localbinary/plugin.go:177 +0x7c
created by github.com/tsuru/tsuru/vendor/github.com/docker/machine/libmachine/drivers/plugin/localbinary.(*Plugin).AttachStream
	/home/travis/gopath/src/github.com/tsuru/tsuru/vendor/github.com/docker/machine/libmachine/drivers/plugin/localbinary/plugin.go:183 +0x67
```

Signed-off-by: Cezar Sa Espinola <cezarsa@gmail.com>
This commit is contained in:
Cezar Sa Espinola
2018-12-28 16:02:20 -02:00
committed by Joffrey F
parent 5a8ce1ae43
commit 55bfb59b67
2 changed files with 14 additions and 10 deletions

View File

@@ -71,10 +71,10 @@ func TestLocalBinaryPluginAddressTimeout(t *testing.T) {
func TestLocalBinaryPluginClose(t *testing.T) {
lbp := &Plugin{}
lbp.stopCh = make(chan bool, 1)
lbp.stopCh = make(chan struct{})
go lbp.Close()
stopped := <-lbp.stopCh
if !stopped {
_, isOpen := <-lbp.stopCh
if isOpen {
t.Fatal("Close did not send a stop message on the proper channel")
}
}
@@ -106,7 +106,7 @@ func TestExecServer(t *testing.T) {
MachineName: machineName,
Executor: fe,
addrCh: make(chan string, 1),
stopCh: make(chan bool, 1),
stopCh: make(chan struct{}),
}
finalErr := make(chan error)