Last active
April 25, 2016 03:58
-
-
Save blixt/2160207dbcb166e3e4e414ced3af0562 to your computer and use it in GitHub Desktop.
Non-blocking reader for Go. Probably a bad idea.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package nonblocking | |
import ( | |
"io" | |
"time" | |
) | |
type NonBlockingReader struct { | |
ch chan []byte | |
rd io.Reader | |
err error | |
} | |
func NewNonBlockingReader(r io.Reader) *NonBlockingReader { | |
nbr := &NonBlockingReader{ | |
ch: make(chan []byte), | |
rd: r, | |
} | |
go nbr.pipe() | |
return nbr | |
} | |
func (nbr *NonBlockingReader) pipe() { | |
d1 := make([]byte, 1024) | |
d2 := make([]byte, 1024) | |
for { | |
n, err := nbr.rd.Read(d1) | |
if n > 0 { | |
nbr.ch <- d1[:n] | |
d1, d2 = d2, d1 | |
} | |
if err != nil { | |
nbr.err = err | |
close(nbr.ch) | |
break | |
} | |
} | |
} | |
func (nbr *NonBlockingReader) Read(p []byte) (n int, err error) { | |
// TODO: Empty channel completely? | |
select { | |
case d := <-nbr.ch: | |
if len(d) > len(p) { | |
// TODO: Buffer data | |
panic("NonBlockingReader: couldn't fit data") | |
} | |
n = copy(p, d) | |
return | |
case <-time.After(1 * time.Millisecond): | |
return 0, nbr.err | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment