Maint: context aware collectLines functions

This commit is contained in:
Quentin McGaw (desktop)
2021-08-16 19:19:33 +00:00
parent 2c73672e64
commit ba16270059
4 changed files with 36 additions and 22 deletions

View File

@@ -1,6 +1,7 @@
package dns package dns
import ( import (
"context"
"regexp" "regexp"
"strings" "strings"
@@ -8,18 +9,24 @@ import (
"github.com/qdm12/golibs/logging" "github.com/qdm12/golibs/logging"
) )
func (l *Loop) collectLines(stdout, stderr <-chan string, done chan<- struct{}) { func (l *Loop) collectLines(ctx context.Context, done chan<- struct{},
stdout, stderr chan string) {
defer close(done) defer close(done)
var line string var line string
var ok bool
for { for {
select { select {
case line, ok = <-stderr: case <-ctx.Done():
case line, ok = <-stdout: // Context should only be canceled after stdout and stderr are done
} // being written to.
if !ok { close(stdout)
close(stderr)
return return
case line = <-stderr:
case line = <-stdout:
} }
line, level := processLogLine(line) line, level := processLogLine(line)
switch level { switch level {
case logging.LevelDebug: case logging.LevelDebug:

View File

@@ -30,12 +30,13 @@ func (l *Loop) setupUnbound(ctx context.Context) (
return nil, nil, nil, err return nil, nil, nil, err
} }
collectLinesDone := make(chan struct{}) linesCollectionCtx, linesCollectionCancel := context.WithCancel(context.Background())
go l.collectLines(stdoutLines, stderrLines, collectLinesDone) lineCollectionDone := make(chan struct{})
go l.collectLines(linesCollectionCtx, lineCollectionDone,
stdoutLines, stderrLines)
closeStreams = func() { closeStreams = func() {
close(stdoutLines) linesCollectionCancel()
close(stderrLines) <-lineCollectionDone
<-collectLinesDone
} }
// use Unbound // use Unbound

View File

@@ -1,6 +1,7 @@
package openvpn package openvpn
import ( import (
"context"
"strings" "strings"
"github.com/fatih/color" "github.com/fatih/color"
@@ -8,20 +9,24 @@ import (
"github.com/qdm12/golibs/logging" "github.com/qdm12/golibs/logging"
) )
func (l *Loop) collectLines(stdout, stderr <-chan string, done chan<- struct{}) { func (l *Loop) collectLines(ctx context.Context, done chan<- struct{},
stdout, stderr chan string) {
defer close(done) defer close(done)
var line string var line string
var ok, errLine bool
for { for {
errLine = false errLine := false
select { select {
case line, ok = <-stdout: case <-ctx.Done():
case line, ok = <-stderr: // Context should only be canceled after stdout and stderr are done
errLine = true // being written to.
} close(stdout)
if !ok { close(stderr)
return return
case line = <-stdout:
case line = <-stderr:
errLine = true
} }
line, level := processLogLine(line) line, level := processLogLine(line)
if line == "" { if line == "" {

View File

@@ -80,11 +80,12 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
continue continue
} }
linesCollectionCtx, linesCollectionCancel := context.WithCancel(context.Background())
lineCollectionDone := make(chan struct{}) lineCollectionDone := make(chan struct{})
go l.collectLines(stdoutLines, stderrLines, lineCollectionDone) go l.collectLines(linesCollectionCtx, lineCollectionDone,
stdoutLines, stderrLines)
closeStreams := func() { closeStreams := func() {
close(stdoutLines) linesCollectionCancel()
close(stderrLines)
<-lineCollectionDone <-lineCollectionDone
} }