...

Source file src/github.com/redis/go-redis/v9/internal/pool/buffer_size_test.go

Documentation: github.com/redis/go-redis/v9/internal/pool

     1  package pool_test
     2  
     3  import (
     4  	"bufio"
     5  	"context"
     6  	"net"
     7  	"unsafe"
     8  
     9  	. "github.com/bsm/ginkgo/v2"
    10  	. "github.com/bsm/gomega"
    11  
    12  	"github.com/redis/go-redis/v9/internal/pool"
    13  	"github.com/redis/go-redis/v9/internal/proto"
    14  )
    15  
    16  var _ = Describe("Buffer Size Configuration", func() {
    17  	var connPool *pool.ConnPool
    18  	ctx := context.Background()
    19  
    20  	AfterEach(func() {
    21  		if connPool != nil {
    22  			connPool.Close()
    23  		}
    24  	})
    25  
    26  	It("should use default buffer sizes when not specified", func() {
    27  		connPool = pool.NewConnPool(&pool.Options{
    28  			Dialer:      dummyDialer,
    29  			PoolSize:    1,
    30  			PoolTimeout: 1000,
    31  		})
    32  
    33  		cn, err := connPool.NewConn(ctx)
    34  		Expect(err).NotTo(HaveOccurred())
    35  		defer connPool.CloseConn(cn)
    36  
    37  		// Check that default buffer sizes are used (32KiB)
    38  		writerBufSize := getWriterBufSizeUnsafe(cn)
    39  		readerBufSize := getReaderBufSizeUnsafe(cn)
    40  
    41  		Expect(writerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 32KiB buffer size
    42  		Expect(readerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 32KiB buffer size
    43  	})
    44  
    45  	It("should use custom buffer sizes when specified", func() {
    46  		customReadSize := 32 * 1024  // 32KB
    47  		customWriteSize := 64 * 1024 // 64KB
    48  
    49  		connPool = pool.NewConnPool(&pool.Options{
    50  			Dialer:          dummyDialer,
    51  			PoolSize:        1,
    52  			PoolTimeout:     1000,
    53  			ReadBufferSize:  customReadSize,
    54  			WriteBufferSize: customWriteSize,
    55  		})
    56  
    57  		cn, err := connPool.NewConn(ctx)
    58  		Expect(err).NotTo(HaveOccurred())
    59  		defer connPool.CloseConn(cn)
    60  
    61  		// Check that custom buffer sizes are used
    62  		writerBufSize := getWriterBufSizeUnsafe(cn)
    63  		readerBufSize := getReaderBufSizeUnsafe(cn)
    64  
    65  		Expect(writerBufSize).To(Equal(customWriteSize))
    66  		Expect(readerBufSize).To(Equal(customReadSize))
    67  	})
    68  
    69  	It("should handle zero buffer sizes by using defaults", func() {
    70  		connPool = pool.NewConnPool(&pool.Options{
    71  			Dialer:          dummyDialer,
    72  			PoolSize:        1,
    73  			PoolTimeout:     1000,
    74  			ReadBufferSize:  0, // Should use default
    75  			WriteBufferSize: 0, // Should use default
    76  		})
    77  
    78  		cn, err := connPool.NewConn(ctx)
    79  		Expect(err).NotTo(HaveOccurred())
    80  		defer connPool.CloseConn(cn)
    81  
    82  		// Check that default buffer sizes are used (32KiB)
    83  		writerBufSize := getWriterBufSizeUnsafe(cn)
    84  		readerBufSize := getReaderBufSizeUnsafe(cn)
    85  
    86  		Expect(writerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 32KiB buffer size
    87  		Expect(readerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 32KiB buffer size
    88  	})
    89  
    90  	It("should use 32KiB default buffer sizes for standalone NewConn", func() {
    91  		// Test that NewConn (without pool) also uses 32KiB buffers
    92  		netConn := newDummyConn()
    93  		cn := pool.NewConn(netConn)
    94  		defer cn.Close()
    95  
    96  		writerBufSize := getWriterBufSizeUnsafe(cn)
    97  		readerBufSize := getReaderBufSizeUnsafe(cn)
    98  
    99  		Expect(writerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 32KiB buffer size
   100  		Expect(readerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 32KiB buffer size
   101  	})
   102  
   103  	It("should use 32KiB defaults even when pool is created directly without buffer sizes", func() {
   104  		// Test the scenario where someone creates a pool directly (like in tests)
   105  		// without setting ReadBufferSize and WriteBufferSize
   106  		connPool = pool.NewConnPool(&pool.Options{
   107  			Dialer:      dummyDialer,
   108  			PoolSize:    1,
   109  			PoolTimeout: 1000,
   110  			// ReadBufferSize and WriteBufferSize are not set (will be 0)
   111  		})
   112  
   113  		cn, err := connPool.NewConn(ctx)
   114  		Expect(err).NotTo(HaveOccurred())
   115  		defer connPool.CloseConn(cn)
   116  
   117  		// Should still get 32KiB defaults because NewConnPool sets them
   118  		writerBufSize := getWriterBufSizeUnsafe(cn)
   119  		readerBufSize := getReaderBufSizeUnsafe(cn)
   120  
   121  		Expect(writerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 32KiB buffer size
   122  		Expect(readerBufSize).To(Equal(proto.DefaultBufferSize)) // Default 32KiB buffer size
   123  	})
   124  })
   125  
   126  // Helper functions to extract buffer sizes using unsafe pointers
   127  func getWriterBufSizeUnsafe(cn *pool.Conn) int {
   128  	cnPtr := (*struct {
   129  		usedAt  int64
   130  		netConn net.Conn
   131  		rd      *proto.Reader
   132  		bw      *bufio.Writer
   133  		wr      *proto.Writer
   134  		// ... other fields
   135  	})(unsafe.Pointer(cn))
   136  
   137  	if cnPtr.bw == nil {
   138  		return -1
   139  	}
   140  
   141  	bwPtr := (*struct {
   142  		err error
   143  		buf []byte
   144  		n   int
   145  		wr  interface{}
   146  	})(unsafe.Pointer(cnPtr.bw))
   147  
   148  	return len(bwPtr.buf)
   149  }
   150  
   151  func getReaderBufSizeUnsafe(cn *pool.Conn) int {
   152  	cnPtr := (*struct {
   153  		usedAt  int64
   154  		netConn net.Conn
   155  		rd      *proto.Reader
   156  		bw      *bufio.Writer
   157  		wr      *proto.Writer
   158  		// ... other fields
   159  	})(unsafe.Pointer(cn))
   160  
   161  	if cnPtr.rd == nil {
   162  		return -1
   163  	}
   164  
   165  	rdPtr := (*struct {
   166  		rd *bufio.Reader
   167  	})(unsafe.Pointer(cnPtr.rd))
   168  
   169  	if rdPtr.rd == nil {
   170  		return -1
   171  	}
   172  
   173  	bufReaderPtr := (*struct {
   174  		buf          []byte
   175  		rd           interface{}
   176  		r, w         int
   177  		err          error
   178  		lastByte     int
   179  		lastRuneSize int
   180  	})(unsafe.Pointer(rdPtr.rd))
   181  
   182  	return len(bufReaderPtr.buf)
   183  }
   184  

View as plain text