Skip to content
This repository has been archived by the owner on Sep 6, 2022. It is now read-only.

Question: Why doesn't Close() close the stream? #9

Closed
prestonvanloon opened this issue May 27, 2019 · 4 comments · Fixed by #166
Closed

Question: Why doesn't Close() close the stream? #9

prestonvanloon opened this issue May 27, 2019 · 4 comments · Fixed by #166

Comments

@prestonvanloon
Copy link

prestonvanloon commented May 27, 2019

I don't understand this bit of the API. When we are handling Closer interfaces, we close them when we are done using the resource. However, this Closer doesn't actually close the stream. It seems we have to call Reset which actually sends an error to the peer.

// Close closes the stream for writing. Reading will still work (that
// is, the remote side can still write).
io.Closer

We have had some pain with this when trying the following logic:

  • Send a message to the peer
  • Close the connection because we don't care about the response or if they received it.

For the second step, if we call Reset then the peer will receive the error only and does not process the message. However, if we call Close and the peer doesn't then we have this dangling connection that we don't care about.

@Stebalien
Copy link
Member

So, Close currently closes the write half. To close the read half, you need to read the EOF off the stream.

This is clearly not a very nice API and was a terrible mistake. I planned to address this once we merged the go-libp2p-core refractor and now we have.

Stebalien added a commit that referenced this issue May 27, 2019
This changes the behavior of `Close` to behave as one would expect: it closes
the stream. The new methods, CloseWrite/CloseRead allow for closing the stream in
a single direction.

Note: This _does not_ implement CancelWrite/CancelRead as our stream muxer
_protocols_ don't support that.

fixes #9
@marten-seemann
Copy link
Contributor

This is clearly not a very nice API and was a terrible mistake. I planned to address this once we merged the go-libp2p-core refractor and now we have.

I don't think this is a mistake. By the way, this exactly how things work for QUIC streams as well. And for TCP connections, if I remember correctly.

@Stebalien
Copy link
Member

The issue is at the API layer, not the protocol layer. That is, users expect Close() to close in both directions and free resources. This is what tcpconn.Close() does. It's also what a close(sock) does in C.

We need to support closing for reading/writing, but we should do the thing users expect by default.

@aschmahmann
Copy link
Contributor

@raulk I see you're the author on the latest version of the PR for this #155. What's the latest state?

Stebalien added a commit that referenced this issue Aug 28, 2020
This changes the behavior of `Close` to behave as one would expect: it closes
the stream. The new methods, CloseWrite/CloseRead allow for closing the stream in
a single direction.

Note: This _does not_ implement CancelWrite/CancelRead as our stream muxer
_protocols_ don't support that.

fixes #9
Stebalien added a commit that referenced this issue Sep 2, 2020
* add CloseRead/CloseWrite on streams

This changes the behavior of `Close` to behave as one would expect: it closes
the stream. The new methods, CloseWrite/CloseRead allow for closing the stream in
a single direction.

Note: This _does not_ implement CancelWrite/CancelRead as our stream muxer
_protocols_ don't support that.

fixes #9

* remove stream util helpers

FullClose and AwaitEOF were introduced to work around the fact that calling
Close on a stream only closed the write half. All users must adapt their code
to the new interfaces, so this change is intentionally breaking.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
4 participants