golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.91k stars 17.52k forks source link

net: clarify documentation on net.ListenConfig.Listen and related calls w.r.t. context #28120

Open theclapp opened 5 years ago

theclapp commented 5 years ago

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

go version go1.11.1 linux/amd64

Does this issue reproduce with the latest release?

Yes

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

GOARCH="amd64" GOOS="linux"

What did you do?

I created a net.ListenConfig.Listen(cancelableCtx, "unix", "/path/to/socket") to create a Unix socket, and called Accept on said listener.

What did you expect to see?

I expected canceling the context to cancel the Accept.

What did you see instead?

The Accept was not canceled.


So maybe my expectation was wrong. I reasoned "Why else would there be a context there if not to cancel (or time out) the Accept calls?". But clearly not.

I asked on the #general channel in the Gophers Slack and was reminded that Dial, for example, specifically says that once Dial completes, the context it's given doesn't affect the connection, and that probably Listen & Accept were similar. That does appear to be the case.

So, for folks like me that are not terribly familiar with network or socket programming, would it be possible to note in the Listen & Accept docs that the given context doesn't affect the later Accept? And maybe even what the Listen context actually does; it wasn't 100% clear to me.

Thanks.

mikioh commented 5 years ago

The method Accept of {TCP,Unix}Listener is part of a connection setup for passive-open connections. It might be better to have AcceptContext(context.Context) (Conn, error) for shooting the root cause of confusion.

theclapp commented 5 years ago

Note that no other Accept or Accept{TCP|Unix} functions currently take a context, so if you/we implemented @mikioh's suggestion, we'd probably want to add several others. Adding it to the net.Listen interface would break the Go 1 compatibility contract though, yes?

In any case, it's easy enough to implement yourself, so it might not be worth it:

go func() {
    <-ctx.Done()
    listener.Close()
}()
mikioh commented 5 years ago

@theclapp,

I think the clarification probably needs to address #10527 partially. Apart from #10527, adding a method to the existing sturct types doesn't mean the violation of Go 1 promise, also doesn't mean changing the existing interfaces such as net.Listener.

theclapp commented 5 years ago

adding a method to the existing struct types doesn't mean the violation of Go 1 promise

Agree.

also doesn't mean changing the existing interfaces such as net.Listener

I agree, it doesn't necessarily mean that. But not doing it would leave a (to me) odd inconsistency between {TCP|Unix}Accept and the net.Listen interface, where the first two would have AcceptContext but the latter wouldn't. But I'll certainly leave it to wiser heads than mine to weigh the importance of these issues.

gmichelo commented 5 years ago

The context passed to a given function should affect only that function, shouldn't it? I am not sure about this, but do we have other cases in Go where a context is kind of "shared" from one method call to another?

Anyhow, I believe that clarify is always a good thing. If we agree on this, I can take care of it.

Regarding adding a new AcceptContext(), I would keep the interface as simple as possible. Accept() is clearly a blocking call and the caller must deal with it. Therefore, I think it would be neater to leave the API as it is.

theclapp commented 5 years ago

Sure, what I'm really asking for is a documentation update. Adding AcceptContext() seems like overkill, especially given that you can roll your own cancellation in four lines (posted earlier).

mikioh commented 5 years ago

If we agree on this, I can take care of it.

Thanks. The deliverable (changelist) should contain the consensus like the following:

gopherbot commented 5 years ago

Change https://golang.org/cl/147378 mentions this issue: net: update documentation for Listen and ListenPacket

gmichelo commented 5 years ago

I updated the documentation, added the check for nil context and more test cases for scenario mentioned above.

Please give it a look when you can, thanks a lot.