go-qemu
go-qemu copied to clipboard
avoid listener goroutine stuck forever on send of error
Using the example pattern of
monitor.Connect()
defer monitor.Disconnect()
cmd := []byte({ "execute": "query-status" }
)
raw, _ := monitor.Run(cmd)
even after the Disconnect() has successfully completed and waiting for 10 seconds there is a goroutine stuck forever at goroutine 20 [chan send]: github.com/digitalocean/go-qemu/qmp.(*SocketMonitor).listen(0xc00037e300, 0x1c8a020, 0xc00000e070, 0xc000100900, 0xc000100960) /pillar/vendor/github.com/digitalocean/go-qemu/qmp/socket.go:188 +0x30e created by github.com/digitalocean/go-qemu/qmp.(*SocketMonitor).Connect /pillar/vendor/github.com/digitalocean/go-qemu/qmp/socket.go:141 +0x325
That is due to an error as a result of the DIsconnect closing the socket. The Run function is not expecting an error and the channel is unbuffered.
Every Connect, Run, Disconnect results in one more stuck goroutine.
The fix in this PR is to make the send be conditional with a timeout. Another approach could be to make the channel buffered. A third approach could be to use a context, have Disconnect cancel the context, and have the listener look for the cancellation on a new done channel.
But offering the simplest fix in this PR.
Closes issue #171