-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change nodejs waiting on pipes to not panic #13689
Conversation
Changelog[uncommitted] (2023-09-02)Bug Fixes
|
4f51bc1
to
ae51816
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a positive change, although it still has a risk of panic. Suggested a fix.
// Channel producing the final response we want to issue to our caller. Will get the result of | ||
// the actual nodejs process we launch, or any results caused by errors in our server/pipes. | ||
responseChannel := make(chan *pulumirpc.RunResponse) | ||
defer close(responseChannel) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will still panic if execNodeJs finishes after pipesDone or handle.Done return an error because that'll exit this function, closing this channel, and then the goroutine will attempt to write to a closed channel, panic, and kill the process.
This can be fixed by using a channel with a buffer of one and dropping the defer close(responseChannel)
. Let the channel be GCed if this function returns with an error. This function is short-lived, so that's not a big deal.
Another alternative is to use the channel just to signal that execNodeJs is done, but store the value in a variable in the scope:
var response *pulumirpc.RunRespnse
haveResponse := make(chan struct{})
go func() {
defer close(haveResponse)
response = ...
}()
This way, the channel will always be closed when execNodeJs finishes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot, it looks like we can just move the close inside the goroutine to fix this as well?
func (host *nodeLanguageHost) execNodejs(ctx context.Context, | ||
responseChannel chan<- *pulumirpc.RunResponse, req *pulumirpc.RunRequest, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call on removing the channel from the function contract here completely.
@dixler was lamenting about something like the problem that caused this panic recently in the context of channels.
Hit this while testing with matrix testing. Fairly frequently the go routine waiting for `pipesDone` would try to write to the response channel and panic because it was already closed. This rewrites the method to only use the response channel for the running program, and we just explictly wait on all three events (pipes, handle, program) and return the first one that triggers. Also it refactors execNodejs to just be a sync method that returns the response. The management of that running in a goroutine and writing to a channel is just kept in Run.
ae51816
to
aea8652
Compare
Description
Hit this while testing with matrix testing. Fairly frequently the go routine waiting for
pipesDone
would try to write to the response channel and panic because it was already closed.This rewrites the method to only use the response channel for the running program, and we just explictly wait on all three events (pipes, handle, program) and return the first one that triggers.
Also it refactors execNodejs to just be a sync method that returns the response. The management of that running in a goroutine and writing to a channel is just kept in Run.
Checklist
make tidy
to update any new dependenciesmake lint
to verify my code passes the lint checkgofumpt
make changelog
and committed thechangelog/pending/<file>
documenting my change