@@ -175,11 +175,12 @@ func (d defaultLogger) Report(event ConnLogKind, conn *Connection, v ...interfac
175175// More on graceful shutdown:
176176// https://www.tarantool.io/en/doc/latest/dev_guide/internals/iproto/graceful_shutdown/
177177type Connection struct {
178- addr net.Addr
179- dialer Dialer
180- c Conn
181- mutex sync.Mutex
182- cond * sync.Cond
178+ addr net.Addr
179+ dialer Dialer
180+ c Conn
181+ mutex sync.Mutex
182+ cond * sync.Cond
183+ slicePool * sync.Pool
183184 // schemaResolver contains a SchemaResolver implementation.
184185 schemaResolver SchemaResolver
185186 // requestId contains the last request ID for requests with nil context.
@@ -373,7 +374,12 @@ func Connect(ctx context.Context, dialer Dialer, opts Opts) (conn *Connection, e
373374 }
374375
375376 conn .cond = sync .NewCond (& conn .mutex )
376-
377+ conn .slicePool = & sync.Pool {
378+ New : func () any {
379+ buf := make ([]byte , 0 , 4096 )
380+ return & buf
381+ },
382+ }
377383 if conn .opts .Reconnect > 0 {
378384 // We don't need these mutex.Lock()/mutex.Unlock() here, but
379385 // runReconnects() expects mutex.Lock() to be set, so it's
@@ -848,8 +854,9 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
848854
849855 go conn .eventer (events )
850856
857+ buf := smallBuf {}
851858 for atomic .LoadUint32 (& conn .state ) != connClosed {
852- respBytes , err := read (r , conn .lenbuf [:])
859+ respBytes , err := read (r , conn .lenbuf [:], conn )
853860 if err != nil {
854861 err = ClientError {
855862 ErrIoError ,
@@ -858,7 +865,7 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
858865 conn .reconnect (err , c )
859866 return
860867 }
861- buf := smallBuf { b : respBytes }
868+ buf . b , buf . p = respBytes , 0
862869 header , code , err := decodeHeader (conn .dec , & buf )
863870 if err != nil {
864871 err = ClientError {
@@ -925,7 +932,7 @@ func (conn *Connection) eventer(events <-chan connWatchEvent) {
925932
926933func (conn * Connection ) newFuture (req Request ) (fut * Future ) {
927934 ctx := req .Ctx ()
928- fut = NewFuture (req )
935+ fut = NewFuture (req , conn )
929936 if conn .rlimit != nil && conn .opts .RLimitAction == RLimitDrop {
930937 select {
931938 case conn .rlimit <- struct {}{}:
@@ -1187,7 +1194,7 @@ func (conn *Connection) timeouts() {
11871194 }
11881195}
11891196
1190- func read (r io.Reader , lenbuf []byte ) (response []byte , err error ) {
1197+ func read (r io.Reader , lenbuf []byte , conn ... * Connection ) (response []byte , err error ) {
11911198 var length uint64
11921199
11931200 if _ , err = io .ReadFull (r , lenbuf ); err != nil {
@@ -1211,7 +1218,15 @@ func read(r io.Reader, lenbuf []byte) (response []byte, err error) {
12111218 return
12121219 }
12131220
1214- response = make ([]byte , length )
1221+ if len (conn ) == 0 {
1222+ response = make ([]byte , length )
1223+ } else {
1224+ response = * conn [0 ].slicePool .Get ().(* []byte )
1225+ if cap (response ) < int (length ) {
1226+ response = make ([]byte , length )
1227+ }
1228+ response = response [:length ]
1229+ }
12151230 _ , err = io .ReadFull (r , response )
12161231
12171232 return
@@ -1232,7 +1247,7 @@ func (conn *Connection) nextRequestId(context bool) (requestId uint32) {
12321247func (conn * Connection ) Do (req Request ) * Future {
12331248 if connectedReq , ok := req .(ConnectedRequest ); ok {
12341249 if connectedReq .Conn () != conn {
1235- fut := NewFuture (req )
1250+ fut := NewFuture (req , conn )
12361251 fut .SetError (errUnknownRequest )
12371252 return fut
12381253 }
0 commit comments