Giter Club home page Giter Club logo

Comments (1)

dennis-tra avatar dennis-tra commented on July 21, 2024

I figured it out after reading the release notes of libp2p 0.12.0:

This is release includes a significant BREAKING CHANGE to the stream interface.

Previously, Close() closed streams for writing, but left them open for reading. Unfortunately, this meant streams would not be garbage collected until either (a) an EOF had been read on the stream or (b) Reset had been called. While technically documented, this behavior was extraordinarily surprising and most libp2p applications end up misusing and leaking streams (leading to memory leaks).

In this release, Close now closes the stream for both reading and writing. Close will not wait for any form of acknowledgment. If acknowledgment is required, the caller must call CloseWrite (described below), then wait on the stream for a response (or an EOF), then call Close() to free the stream object.

To close the stream for writing only, the user should call CloseWrite(). Close write flushes any in-progress writes, then sends an EOF.

The user may now call CloseRead() to close the stream for reading only. CloseRead() will interrupt any in-progress reads with an error and prevent further reads from succeeding. At the protocol level, the behavior of CloseRead() is implementation defined.

Yamux and Mplex will throw away incoming data on a closed stream.
QUIC will return an error to the sender.
When done with a stream, the user must call either Close() or Reset() to discard the stream, even after calling CloseRead() and/or CloseWrite().

Now after I have written to the stream, I'm waiting for the remote peer to close/reset the connection:

func WaitForEOF(s network.Stream) error {
	timeout := time.After(10 * time.Second)
	done := make(chan error)
	go func() {
		buf := make([]byte, 1)
		n, err := s.Read(buf)
		if err == io.EOF && n == 0 {
			err = nil
		} else if n != 0 {
			err = fmt.Errorf("stream returned data unexpectedly")
		}
		done <- err
		close(done)
	}()
	select {
	case <-timeout:
		return fmt.Errorf("timeout")
	case err := <-done:
		return err
	}
}

Closing of the stream is handled outside of WaitForEOF.

from go-libp2p-core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.