Skip to content

Commit b478396

Browse files
authored
Merge pull request #19 from carlmontanari/uhoh-fix-concurrency
fix: fix borked concurrency bits
2 parents a676023 + 61c39b8 commit b478396

File tree

2 files changed

+53
-21
lines changed

2 files changed

+53
-21
lines changed

commando/cmdo.go

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
114119
func (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{},
321330
func (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

362386
func (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
}

go.sum

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
3131
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
3232
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
3333
github.com/scrapli/scrapligo v1.0.0/go.mod h1:jvRMdb90MNnswMiku8UNXj8JZaOIPhwhcqqFwr9qeoY=
34-
github.com/scrapli/scrapligo v1.0.2 h1:IzZPtfuuINvewd72Jjt91fr43s3y1shI4rXWnKmpC7A=
35-
github.com/scrapli/scrapligo v1.0.2/go.mod h1:jvRMdb90MNnswMiku8UNXj8JZaOIPhwhcqqFwr9qeoY=
36-
github.com/scrapli/scrapligo v1.0.3 h1:nLqW1FquCG//l8lzPS9rGIMX/9fe8v9dJoupnem3Hdc=
37-
github.com/scrapli/scrapligo v1.0.3/go.mod h1:jvRMdb90MNnswMiku8UNXj8JZaOIPhwhcqqFwr9qeoY=
3834
github.com/scrapli/scrapligo v1.1.0 h1:KjCam57kIV2rlxAQg/J1G7v/xgRHvpJF+Gjz+LXhQaI=
3935
github.com/scrapli/scrapligo v1.1.0/go.mod h1:jvRMdb90MNnswMiku8UNXj8JZaOIPhwhcqqFwr9qeoY=
4036
github.com/scrapli/scrapligocfg v1.0.0 h1:540SuGqqM6rKN87SLCfR54IageQ6s3a/ZOycGRgbbak=

0 commit comments

Comments
 (0)