buffered io.Pipe implementation?

1,429 views
Skip to first unread message

Brad Fitzpatrick

unread,
Nov 11, 2014, 11:37:16 PM11/11/14
to golang-dev
Before I reinvent a wheel, has anybody written something like a buffered io.Pipe? I need one for HTTP/2.

I need Writes to buffer and not block (I can guarantee it's bounded before I do the Write), and
I need Reads to do their normal blocking thing like an io.Pipe.

I can use an io.Pipe for now, but it's not ideal.

As background:
The HTTP/2 code has one goroutine reading frames from the network, and then processing those frames. The DATA frame processing involve looking up which stream (HTTP request) they're associated with and writing it to that pipe (the reading side of which is an http.Request.Body)

But if I use an io.Pipe, an http.Handler is doing some incremental processing of their Request.Body, they can stall other handlers from reading their request bodies.

HTTP/2 already has negotiation of buffer sizes and flow control, so I can be sure clients won't be sending more than we've asked for (else they get errors). I'm not concerned about buffers going crazy. i.e. there's already pushback. I just need a buffer that's the size we've advertised (or growing up to the advertised size), so just that stream being slow with their reads gets pushback all the way to the sender, without stalling the goroutine that's reading frames for other http.Handlers.

If it's possible to compose such a beast using primitives already in the standard library, it's either not obvious, or I'll blame sleepiness. It's also not much code, but effectively forking http://golang.org/src/pkg/io/pipe.go and making it even more complicated isn't my first choice if there's an easier or cleaner way.

Gustavo Niemeyer

unread,
Nov 12, 2014, 12:21:31 AM11/12/14
to Brad Fitzpatrick, golang-dev
This might be helpful:


--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Keith Rarick

unread,
Nov 12, 2014, 2:21:49 AM11/12/14
to Brad Fitzpatrick, golang-dev

Han-Wen Nienhuys

unread,
Nov 12, 2014, 2:30:55 AM11/12/14
to Brad Fitzpatrick, golang-dev
sounds very similar to the channel dispatch for SSH. SSH uses

https://code.google.com/p/go/source/browse/ssh/buffer.go?repo=crypto#167

It's not exported, but you're welcome to copy & paste or figure out a
shared place for this code.
> --
> You received this message because you are subscribed to the Google Groups
> "golang-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-dev+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Han-Wen Nienhuys
Google Munich
han...@google.com

Dave Cheney

unread,
Nov 12, 2014, 3:05:45 AM11/12/14
to Han-Wen Nienhuys, Brad Fitzpatrick, golang-dev

Does Atwood's rule of threes come into effect at this point ?

Brad Fitzpatrick

unread,
Nov 12, 2014, 10:17:17 AM11/12/14
to Gustavo Niemeyer, golang-dev
That Tee doesn't seem to do what I need. I would expect to see a sync.Cond and for Read to use it, waiting for new data.

Brad Fitzpatrick

unread,
Nov 12, 2014, 12:12:28 PM11/12/14
to Keith Rarick, golang-dev
Keith, looks great.

Permission to use that? If so, either I can copy it, or you could send a PR to github.com/bradfitz/http2 with the tests as well, but without integrating it yet.



Keith Rarick

unread,
Nov 12, 2014, 2:34:25 PM11/12/14
to Brad Fitzpatrick, golang-dev
Certainly you can use it. PR coming up.
Reply all
Reply to author
Forward
0 new messages