in pkg/client/client_v2.go [806:842]
func (c *clientV2) actionRoundTrip(actionResults chan *proto.ActionResponse) {
actionsCtx, actionsCancel := context.WithCancel(c.ctx)
defer actionsCancel()
// Return immediately if we can't establish an initial RPC connection.
actionsClient, err := c.client.Actions(actionsCtx)
if err != nil {
c.errCh <- err
return
}
// wg tracks when the reader and writer loops terminate.
var wg sync.WaitGroup
// readerDone is closed by the reader loop when it terminates, so the
// writer loop knows to return as well.
readerDone := make(chan struct{})
// action requests
wg.Add(1)
go func() {
defer wg.Done()
defer close(readerDone)
c.actionsReader(actionsClient, actionResults)
}()
// action responses
wg.Add(1)
go func() {
defer wg.Done()
defer actionsClient.CloseSend()
c.actionsWriter(actionsClient, actionResults, readerDone)
}()
// Wait for reader and writer to finish before returning.
wg.Wait()
}