Skip to content

Commit

Permalink
Fix exec deadlock when emitter is not Typer intf
Browse files Browse the repository at this point in the history
  • Loading branch information
djdv committed Aug 22, 2021
1 parent 4ade007 commit 936b3a0
Showing 1 changed file with 34 additions and 20 deletions.
54 changes: 34 additions & 20 deletions executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,32 +50,46 @@ func (x *executor) Execute(req *Request, re ResponseEmitter, env Environment) er
return err
}
}
maybeStartPostRun := func(formatters PostRunMap) <-chan error {
var (
postRun func(Response, ResponseEmitter) error
postRunCh = make(chan error)
)

// contains the error returned by PostRun
errCh := make(chan error, 1)
if cmd.PostRun != nil {
if typer, ok := re.(interface {
Type() PostRunType
}); ok && cmd.PostRun[typer.Type()] != nil {
var (
res Response
lower = re
)

re, res = NewChanResponsePair(req)
if postRun == nil {
close(postRunCh)
return postRunCh
}

go func() {
defer close(errCh)
errCh <- lower.CloseWithError(cmd.PostRun[typer.Type()](res, lower))
}()
// check if we have a formatter for this emitter type
typer, isTyper := re.(interface {
Type() PostRunType
})
if isTyper &&
formatters[typer.Type()] != nil {
postRun = formatters[typer.Type()]
} else {
close(postRunCh)
return postRunCh
}
} else {
// not using this channel today
close(errCh)

// redirect emitter to us
// and start waiting for emissions
var (
postRes Response
postEmitter = re
)
re, postRes = NewChanResponsePair(req)
go func() {
defer close(postRunCh)
postRunCh <- postEmitter.CloseWithError(postRun(postRes, postEmitter))
}()
return postRunCh
}

postRunCh := maybeStartPostRun(cmd.PostRun)
runCloseErr := re.CloseWithError(cmd.Run(req, re, env))
postCloseErr := <-errCh
postCloseErr := <-postRunCh
switch runCloseErr {
case ErrClosingClosedEmitter, nil:
default:
Expand Down

0 comments on commit 936b3a0

Please sign in to comment.