From 6bbbfefb75c89afa1ed0d4100ffa8522359f45af Mon Sep 17 00:00:00 2001 From: aler9 <46489434+aler9@users.noreply.github.com> Date: Sat, 27 Jun 2020 16:06:16 +0200 Subject: [PATCH] reuse interleaved frame buffer to minimize ram and cpu --- conn-client.go | 12 ++++++++---- conn-server.go | 4 ++-- interleaved-frame.go | 26 +++++++++++--------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/conn-client.go b/conn-client.go index fbfff0a0..6d44d332 100644 --- a/conn-client.go +++ b/conn-client.go @@ -144,7 +144,7 @@ func (c *ConnClient) WriteRequestNoResponse(req *Request) error { } // 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)) b, err := c.br.ReadByte() if err != nil { @@ -153,16 +153,20 @@ func (c *ConnClient) ReadInterleavedFrameOrResponse() (interface{}, error) { c.br.UnreadByte() 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) } // 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)) - return interleavedFrameRead(c.br) + return frame.read(c.br) } // WriteInterleavedFrame writes an InterleavedFrame. diff --git a/conn-server.go b/conn-server.go index 7a095561..2c6afe4e 100644 --- a/conn-server.go +++ b/conn-server.go @@ -75,9 +75,9 @@ func (s *ConnServer) WriteResponse(res *Response) error { } // 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)) - return interleavedFrameRead(s.br) + return frame.read(s.br) } // WriteInterleavedFrame writes an InterleavedFrame. diff --git a/interleaved-frame.go b/interleaved-frame.go index b18dfe7e..539d816e 100644 --- a/interleaved-frame.go +++ b/interleaved-frame.go @@ -8,9 +8,7 @@ import ( ) const ( - _INTERLEAVED_FRAME_MAGIC = 0x24 - _INTERLEAVED_FRAME_MAX_SIZE = 512 * 1024 - _INTERLEAVED_FRAME_MAX_CONTENT_SIZE = (_INTERLEAVED_FRAME_MAX_SIZE - 4) + _INTERLEAVED_FRAME_MAGIC = 0x24 ) // InterleavedFrame is a structure that allows to send and receive binary data @@ -21,34 +19,32 @@ type InterleavedFrame struct { Content []byte } -func interleavedFrameRead(r io.Reader) (*InterleavedFrame, error) { +func (f *InterleavedFrame) read(r io.Reader) error { var header [4]byte _, err := io.ReadFull(r, header[:]) if err != nil { - return nil, err + return err } 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:])) - if framelen > _INTERLEAVED_FRAME_MAX_SIZE { - return nil, fmt.Errorf("frame length greater than maximum allowed (%d vs %d)", - framelen, _INTERLEAVED_FRAME_MAX_SIZE) + if framelen > len(f.Content) { + return fmt.Errorf("frame length greater than maximum allowed (%d vs %d)", + framelen, len(f.Content)) } - f := &InterleavedFrame{ - Channel: header[1], - Content: make([]byte, framelen), - } + f.Channel = header[1] + f.Content = f.Content[:framelen] _, err = io.ReadFull(r, f.Content) if err != nil { - return nil, err + return err } - return f, nil + return nil } func (f *InterleavedFrame) write(bw *bufio.Writer) error {