reuse interleaved frame buffer to minimize ram and cpu

This commit is contained in:
aler9
2020-06-27 16:06:16 +02:00
parent 5f06349c87
commit 6bbbfefb75
3 changed files with 21 additions and 21 deletions

View File

@@ -144,7 +144,7 @@ func (c *ConnClient) WriteRequestNoResponse(req *Request) error {
} }
// ReadInterleavedFrameOrResponse reads an InterleavedFrame or a Response. // ReadInterleavedFrameOrResponse reads an InterleavedFrame or a Response.
func (c *ConnClient) ReadInterleavedFrameOrResponse() (interface{}, error) { func (c *ConnClient) ReadInterleavedFrameOrResponse(frame *InterleavedFrame) (interface{}, error) {
c.conf.NConn.SetReadDeadline(time.Now().Add(c.conf.ReadTimeout)) c.conf.NConn.SetReadDeadline(time.Now().Add(c.conf.ReadTimeout))
b, err := c.br.ReadByte() b, err := c.br.ReadByte()
if err != nil { if err != nil {
@@ -153,16 +153,20 @@ func (c *ConnClient) ReadInterleavedFrameOrResponse() (interface{}, error) {
c.br.UnreadByte() c.br.UnreadByte()
if b == _INTERLEAVED_FRAME_MAGIC { if b == _INTERLEAVED_FRAME_MAGIC {
return interleavedFrameRead(c.br) err := frame.read(c.br)
if err != nil {
return nil, err
}
return frame, err
} }
return readResponse(c.br) return readResponse(c.br)
} }
// ReadInterleavedFrame reads an InterleavedFrame. // ReadInterleavedFrame reads an InterleavedFrame.
func (c *ConnClient) ReadInterleavedFrame() (*InterleavedFrame, error) { func (c *ConnClient) ReadInterleavedFrame(frame *InterleavedFrame) error {
c.conf.NConn.SetReadDeadline(time.Now().Add(c.conf.ReadTimeout)) c.conf.NConn.SetReadDeadline(time.Now().Add(c.conf.ReadTimeout))
return interleavedFrameRead(c.br) return frame.read(c.br)
} }
// WriteInterleavedFrame writes an InterleavedFrame. // WriteInterleavedFrame writes an InterleavedFrame.

View File

@@ -75,9 +75,9 @@ func (s *ConnServer) WriteResponse(res *Response) error {
} }
// ReadInterleavedFrame reads an InterleavedFrame. // ReadInterleavedFrame reads an InterleavedFrame.
func (s *ConnServer) ReadInterleavedFrame() (*InterleavedFrame, error) { func (s *ConnServer) ReadInterleavedFrame(frame *InterleavedFrame) error {
s.conf.NConn.SetReadDeadline(time.Now().Add(s.conf.ReadTimeout)) s.conf.NConn.SetReadDeadline(time.Now().Add(s.conf.ReadTimeout))
return interleavedFrameRead(s.br) return frame.read(s.br)
} }
// WriteInterleavedFrame writes an InterleavedFrame. // WriteInterleavedFrame writes an InterleavedFrame.

View File

@@ -8,9 +8,7 @@ import (
) )
const ( const (
_INTERLEAVED_FRAME_MAGIC = 0x24 _INTERLEAVED_FRAME_MAGIC = 0x24
_INTERLEAVED_FRAME_MAX_SIZE = 512 * 1024
_INTERLEAVED_FRAME_MAX_CONTENT_SIZE = (_INTERLEAVED_FRAME_MAX_SIZE - 4)
) )
// InterleavedFrame is a structure that allows to send and receive binary data // InterleavedFrame is a structure that allows to send and receive binary data
@@ -21,34 +19,32 @@ type InterleavedFrame struct {
Content []byte Content []byte
} }
func interleavedFrameRead(r io.Reader) (*InterleavedFrame, error) { func (f *InterleavedFrame) read(r io.Reader) error {
var header [4]byte var header [4]byte
_, err := io.ReadFull(r, header[:]) _, err := io.ReadFull(r, header[:])
if err != nil { if err != nil {
return nil, err return err
} }
if header[0] != _INTERLEAVED_FRAME_MAGIC { if header[0] != _INTERLEAVED_FRAME_MAGIC {
return nil, fmt.Errorf("wrong magic byte (0x%.2x)", header[0]) return fmt.Errorf("wrong magic byte (0x%.2x)", header[0])
} }
framelen := int(binary.BigEndian.Uint16(header[2:])) framelen := int(binary.BigEndian.Uint16(header[2:]))
if framelen > _INTERLEAVED_FRAME_MAX_SIZE { if framelen > len(f.Content) {
return nil, fmt.Errorf("frame length greater than maximum allowed (%d vs %d)", return fmt.Errorf("frame length greater than maximum allowed (%d vs %d)",
framelen, _INTERLEAVED_FRAME_MAX_SIZE) framelen, len(f.Content))
} }
f := &InterleavedFrame{ f.Channel = header[1]
Channel: header[1], f.Content = f.Content[:framelen]
Content: make([]byte, framelen),
}
_, err = io.ReadFull(r, f.Content) _, err = io.ReadFull(r, f.Content)
if err != nil { if err != nil {
return nil, err return err
} }
return f, nil return nil
} }
func (f *InterleavedFrame) write(bw *bufio.Writer) error { func (f *InterleavedFrame) write(bw *bufio.Writer) error {