Skip to content
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

net/http: ListenAndServe example deadlocks in playground #50045

Open
thaJeztah opened this issue Dec 8, 2021 · 6 comments
Open

net/http: ListenAndServe example deadlocks in playground #50045

thaJeztah opened this issue Dec 8, 2021 · 6 comments

Comments

@thaJeztah
Copy link
Contributor

@thaJeztah thaJeztah commented Dec 8, 2021

What version of Go are you using (go version)?

$ go version
go1.17.4

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env

What did you do?

Run the go playground example for net/http.ListenAndServe() (https://play.golang.org/p/j01H9doftSz)

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [IO wait]:
internal/poll.runtime_pollWait(0x7f004b011eb8, 0x72)
	/usr/local/go-faketime/src/runtime/netpoll.go:234 +0x89
internal/poll.(*pollDesc).wait(0xc000134000, 0x4, 0x0)
	/usr/local/go-faketime/src/internal/poll/fd_poll_runtime.go:84 +0x32
internal/poll.(*pollDesc).waitRead(...)
	/usr/local/go-faketime/src/internal/poll/fd_poll_runtime.go:89
internal/poll.(*FD).Accept(0xc000134000)
	/usr/local/go-faketime/src/internal/poll/fd_unix.go:402 +0x22c
net.(*netFD).accept(0xc000134000)
	/usr/local/go-faketime/src/net/fd_unix.go:173 +0x35
net.(*TCPListener).accept(0xc00000c0f0)
	/usr/local/go-faketime/src/net/tcpsock_posix.go:140 +0x28
net.(*TCPListener).Accept(0xc00000c0f0)
	/usr/local/go-faketime/src/net/tcpsock.go:262 +0x3d
net/http.(*Server).Serve(0xc000132000, {0x6962b0, 0xc00000c0f0})
	/usr/local/go-faketime/src/net/http/server.go:3002 +0x394
net/http.(*Server).ListenAndServe(0xc000132000)
	/usr/local/go-faketime/src/net/http/server.go:2931 +0x7d
net/http.ListenAndServe(...)
	/usr/local/go-faketime/src/net/http/server.go:3185
main.main()
	/tmp/sandbox528359240/prog.go:20 +0xb4

Program exited.

What did you expect to see?

Hello, world!

What did you see instead?

See above

@seankhliao seankhliao changed the title go playground: net/http.ListenAndServe() example produces a deadlock net/http: ListenAndServe example deadlocks in playground Dec 8, 2021
@bcmills
Copy link
Member

@bcmills bcmills commented Dec 10, 2021

It's, uh... not wrong? If you assume that the only connections that will be accepted come from the program itself (which AFAICT is a valid assumption in the faked world of the Playground), then it really is deadlocked.

Shoving the server into the background and making an actual call to it seems to work:
https://go.dev/play/p/PCryrIf6hEw

@thaJeztah
Copy link
Contributor Author

@thaJeztah thaJeztah commented Dec 10, 2021

Thanks for looking!

So the TL;DR of this was that I was chatting with someone on my phone, and thought http.ListenAndServe() was a nice example to show "this is one of the things that make Go nice!". Then clicked the "run example", and saw the ugly trace (which likely wasn't the intent of that example, and very likely will confuse users).

Your updated example looks good (perhaps even better, as it's a more complete example); slightly concerned if the added complexity will distract from the http.ListenAndServe() topic itself.

@bcmills
Copy link
Member

@bcmills bcmills commented Dec 10, 2021

FWIW, I think that update may actually be racy. (I'm not sure what it happens to do if the http.Get goroutine executes before the ListenAndServe goroutine has opened the socket.)

If you're going to use ListenAndServe for an application that has actual tests, you'll probably have to write a spin-loop that waits for the server to come up before starting the tests. IMO it's much more ergonomic to just use net.Listen and http.Serve separately, so that you can establish the Listener before starting the requests to it.

@bcmills
Copy link
Member

@bcmills bcmills commented Dec 10, 2021

A more appropriate example is probably something like https://go.dev/play/p/UFd9OAIjx_B.

@seankhliao
Copy link
Contributor

@seankhliao seankhliao commented Dec 10, 2021

that's almost identical to the "Http Server" example in the playground dropdown

@bcmills
Copy link
Member

@bcmills bcmills commented Dec 10, 2021

So it is. Perfect!

Then maybe we should replace the ListenAndServe example with a deprecation notice. 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants