rpc: chunk JSON parts of communication + refactoring

JSONDecoder was buffering more of connection data than just the JSON.
=> Unchunker didn't bother and just started unchunking.

While chaining JSONDecoder.Buffered() and the connection using
ChainedReader works, it's still not a clean architecture.

=> Every JSON message is now wrapped in a chunked stream
   (chunked and unchunked)
   => no special-cases
=> Keep ChainedReader, might be useful later on...
This commit is contained in:
Christian Schwarz
2017-05-12 20:39:11 +02:00
parent feabf1abcd
commit 74719ad846
4 changed files with 181 additions and 67 deletions
+14 -1
View File
@@ -26,7 +26,7 @@ func NewUnchunker(conn io.Reader) *Unchunker {
func (c *Unchunker) Read(b []byte) (n int, err error) {
if c.finishErr != nil {
return 0, err
return 0, c.finishErr
}
if c.remainingChunkBytes == 0 {
@@ -68,6 +68,19 @@ func (c *Unchunker) Read(b []byte) (n int, err error) {
}
func (c *Unchunker) Close() (err error) {
buf := make([]byte, 4096)
for err == nil {
_, err = c.Read(buf)
if err == io.EOF {
err = nil
break
}
}
return
}
func min(a, b int) int {
if a < b {
return a
+36
View File
@@ -0,0 +1,36 @@
package util
import (
"io"
)
type ChainedReader struct {
Readers []io.Reader
curReader int
}
func NewChainedReader(reader ...io.Reader) *ChainedReader {
return &ChainedReader{
Readers: reader,
curReader: 0,
}
}
func (c *ChainedReader) Read(buf []byte) (n int, err error) {
n = 0
for c.curReader < len(c.Readers) {
n, err = c.Readers[c.curReader].Read(buf)
if err == io.EOF {
c.curReader++
continue
}
break
}
if c.curReader == len(c.Readers) {
err = io.EOF // actually, there was no gap
}
return
}