@@ -110,6 +110,11 @@ type appCfg struct {
110110 commands string // commands to send
111111}
112112
113+ type respTuple struct {
114+ name string
115+ resp []interface {}
116+ }
117+
113118// run runs the commando.
114119func (app * appCfg ) run () error {
115120 i := & inventory {}
@@ -125,7 +130,10 @@ func (app *appCfg) run() error {
125130 }
126131
127132 rw := app .newResponseWriter (app .output )
128- rCh := make (chan []interface {})
133+
134+ respCh := make (chan respTuple )
135+
136+ doneCh := make (chan interface {})
129137
130138 if app .output == fileOutput {
131139 log .SetOutput (os .Stderr )
@@ -136,14 +144,15 @@ func (app *appCfg) run() error {
136144 wg .Add (len (i .Devices ))
137145
138146 for n , d := range i .Devices {
139- go app .runOperations (n , d , rCh )
140-
141- resps := <- rCh
142- go app .outputResult (wg , rw , n , resps )
147+ go app .runOperations (n , d , respCh )
143148 }
144149
150+ go app .outputResult (wg , rw , respCh , doneCh )
151+
145152 wg .Wait ()
146153
154+ doneCh <- nil
155+
147156 if app .output == fileOutput {
148157 log .Infof ("outputs have been saved to '%s' directory" , app .outDir )
149158 }
@@ -321,10 +330,13 @@ func runCommands(name string, d *device, driver *network.Driver) ([]interface{},
321330func (app * appCfg ) runOperations (
322331 name string ,
323332 d * device ,
324- rCh chan <- [] interface {} ) {
333+ rCh chan <- respTuple ) {
325334 driver , err := app .openCoreConn (name , d )
326335 if err != nil {
327- rCh <- nil
336+ rCh <- respTuple {
337+ name : name ,
338+ resp : nil ,
339+ }
328340
329341 return
330342 }
@@ -333,7 +345,10 @@ func (app *appCfg) runOperations(
333345
334346 cfgResponses , err := runCfg (name , d , driver )
335347 if err != nil {
336- rCh <- nil
348+ rCh <- respTuple {
349+ name : name ,
350+ resp : nil ,
351+ }
337352
338353 return
339354 }
@@ -342,31 +357,52 @@ func (app *appCfg) runOperations(
342357
343358 err = runConfigs (name , d , driver )
344359 if err != nil {
345- rCh <- nil
360+ rCh <- respTuple {
361+ name : name ,
362+ resp : nil ,
363+ }
346364
347365 return
348366 }
349367
350368 cmdResponses , err := runCommands (name , d , driver )
351369 if err != nil {
352- rCh <- nil
370+ rCh <- respTuple {
371+ name : name ,
372+ resp : nil ,
373+ }
353374
354375 return
355376 }
356377
357378 responses = append (responses , cmdResponses ... )
358379
359- rCh <- responses
380+ rCh <- respTuple {
381+ name : name ,
382+ resp : responses ,
383+ }
360384}
361385
362386func (app * appCfg ) outputResult (
363387 wg * sync.WaitGroup ,
364388 rw responseWriter ,
365- name string ,
366- r []interface {}) {
367- defer wg .Done ()
368-
369- if err := rw .WriteResponse (r , name ); err != nil {
370- log .Errorf ("error while writing the response: %v" , err )
389+ rCh chan respTuple ,
390+ doneCh chan interface {},
391+ ) {
392+ for {
393+ select {
394+ case <- doneCh :
395+ return
396+ case r := <- rCh :
397+ if err := rw .WriteResponse (r .resp , r .name ); err != nil {
398+ log .Errorf ("error while writing the response: %v" , err )
399+
400+ // don't defer the wg.Done because it needs to always be decremented at each
401+ // iteration!
402+ wg .Done ()
403+ } else {
404+ wg .Done ()
405+ }
406+ }
371407 }
372408}
0 commit comments