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

Methods to read/write on plain io.{Reader,Writer} #186

Closed
gobwas opened this issue Nov 17, 2016 · 15 comments
Closed

Methods to read/write on plain io.{Reader,Writer} #186

gobwas opened this issue Nov 17, 2016 · 15 comments

Comments

@gobwas
Copy link

gobwas commented Nov 17, 2016

Hello!

Thank you for the great library! 🚀

In application I developing it is very hard restrictions on memory consumption.
So I need to reuse very lot of things, and, of course, buffers.

Is it possible to export some io methods for just to do handshake on plain net.Conn or io.ReadWriter, and read/write functions on it?

I mean something like this:

conn, err := req.Hijack()
err = websocket.Upgrade(conn)

// eventually
err = websocket.Write(conn, myBytes)

// eventually
bts, err := websocket.Read(conn)
@gobwas gobwas changed the title Methods to read/write from plain net.Conn. Methods to read/write on plain io.{Reader,Writer} Nov 17, 2016
@garyburd
Copy link
Contributor

I am not in favor of these functions because they make the package more complicated. Please describe the buffers that are a concern for your application and how your application will do things differently.

@gobwas
Copy link
Author

gobwas commented Nov 19, 2016

I think there could not be any complication with optional extraction of buffers from conn.
I mean the buffers that lay inside Conn struct (writeBuf and br).
Inside my app Im planning to use epoll to detect the connections that ready to produce some bytes.
Then use buffer from sync.Pool to read frames from active connection.

So pseudocode could look like this:

var epolledConns chan net.Conn
for conn := range epolledConns {
  var buf *bufio.Reader
  buf = acquireBuffer(conn, readBufferSize)

  bts, typ, err := websocket.ReadFrame(buf)
  // ...
}

@gobwas
Copy link
Author

gobwas commented Nov 19, 2016

By the way, it is very conformable with this issue too.

@garyburd
Copy link
Contributor

garyburd commented Nov 19, 2016

I will not add a feature that requires the app to use epoll directly to make the feature useful. You should copy the package and modify it to meet your needs.

The proposed feature makes the package more complicated for users because it introduces a second way of using the package.

@gobwas
Copy link
Author

gobwas commented Nov 21, 2016

It is not required for the app to use epoll directly. For example, you always know when you want to write data to the socket – so you dont need to keep write buffer for idle connections. With read it also could be useful when you just want to read response after you wrote request.

@gobwas
Copy link
Author

gobwas commented Nov 21, 2016

Alternatively, it is possible just to implement exported constructor of Conn, that accepts net.Conn, bufio.Reader, bufio.Writer. What do you think?

@garyburd
Copy link
Contributor

garyburd commented Nov 21, 2016

you just want to read response after you wrote request.

The application must read the connection to process control messages.

exported constructor of Conn, that accepts net.Conn, bufio.Reader, bufio.Writer

How will be bufio.Reader differ from the one created by the package? The package does not use a bufio.Writer.

@gobwas
Copy link
Author

gobwas commented Nov 21, 2016

It will not differ, it will be the same, but reused.
Yeah, I realised that there is no buffo.Writer. So, the constructor could accept bufio.Reader with net.Conn inside, and []byte. This kind of constructor could help to reuse allocated []byte.

@garyburd
Copy link
Contributor

New features require a justification and must be useful to more than one application.

Describe why reusing these buffers will provide a significant performance improvement to your application and how this feature might be useful to other applications.

@gobwas
Copy link
Author

gobwas commented Nov 21, 2016

Reusing these buffers will not increase performance. It will be at most the same. But, it will reduce the memory consumption by the application. And this is actual for projects with lots of idle connections.

@garyburd
Copy link
Contributor

Are you planning to share the buffers between connections? You will not decrease the memory required by the application if you reuse buffers as connections are opened and closed.

@gobwas
Copy link
Author

gobwas commented Nov 23, 2016

Yes, I am planning to share the buffers between connections. But I will reuse them not on conn open/close, but on conn ready to read/write.

@garyburd
Copy link
Contributor

It is not possible to share read buffers without use epoll. I will not add a feature that requires the app to use epoll directly to make the feature useful. You should copy the package and modify it to meet your needs.

@garyburd
Copy link
Contributor

I have work in progress to fix #9. You will have complete control of the write buffer when this work is complete.

@gobwas
Copy link
Author

gobwas commented Nov 23, 2016

Sounds useful. Thanks.

@gorilla gorilla locked and limited conversation to collaborators Feb 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants