...

Source file src/github.com/gomodule/redigo/redisx/connmux_test.go

Documentation: github.com/gomodule/redigo/redisx

     1  // Copyright 2014 Gary Burd
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"): you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    11  // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    12  // License for the specific language governing permissions and limitations
    13  // under the License.
    14  
    15  package redisx_test
    16  
    17  import (
    18  	"net/textproto"
    19  	"sync"
    20  	"testing"
    21  
    22  	"github.com/gomodule/redigo/internal/redistest"
    23  	"github.com/gomodule/redigo/redis"
    24  	"github.com/gomodule/redigo/redisx"
    25  )
    26  
    27  func TestConnMux(t *testing.T) {
    28  	c, err := redistest.Dial()
    29  	if err != nil {
    30  		t.Fatalf("error connection to database, %v", err)
    31  	}
    32  	m := redisx.NewConnMux(c)
    33  	defer m.Close()
    34  
    35  	c1 := m.Get()
    36  	c2 := m.Get()
    37  	c1.Send("ECHO", "hello")
    38  	c2.Send("ECHO", "world")
    39  	c1.Flush()
    40  	c2.Flush()
    41  	s, err := redis.String(c1.Receive())
    42  	if err != nil {
    43  		t.Fatal(err)
    44  	}
    45  	if s != "hello" {
    46  		t.Fatalf("echo returned %q, want %q", s, "hello")
    47  	}
    48  	s, err = redis.String(c2.Receive())
    49  	if err != nil {
    50  		t.Fatal(err)
    51  	}
    52  	if s != "world" {
    53  		t.Fatalf("echo returned %q, want %q", s, "world")
    54  	}
    55  	c1.Close()
    56  	c2.Close()
    57  }
    58  
    59  func TestConnMuxClose(t *testing.T) {
    60  	c, err := redistest.Dial()
    61  	if err != nil {
    62  		t.Fatalf("error connection to database, %v", err)
    63  	}
    64  	m := redisx.NewConnMux(c)
    65  	defer m.Close()
    66  
    67  	c1 := m.Get()
    68  	c2 := m.Get()
    69  
    70  	if err := c1.Send("ECHO", "hello"); err != nil {
    71  		t.Fatal(err)
    72  	}
    73  	if err := c1.Close(); err != nil {
    74  		t.Fatal(err)
    75  	}
    76  
    77  	if err := c2.Send("ECHO", "world"); err != nil {
    78  		t.Fatal(err)
    79  	}
    80  	if err := c2.Flush(); err != nil {
    81  		t.Fatal(err)
    82  	}
    83  
    84  	s, err := redis.String(c2.Receive())
    85  	if err != nil {
    86  		t.Fatal(err)
    87  	}
    88  	if s != "world" {
    89  		t.Fatalf("echo returned %q, want %q", s, "world")
    90  	}
    91  	c2.Close()
    92  }
    93  
    94  func BenchmarkConn(b *testing.B) {
    95  	b.StopTimer()
    96  	c, err := redistest.Dial()
    97  	if err != nil {
    98  		b.Fatalf("error connection to database, %v", err)
    99  	}
   100  	defer c.Close()
   101  	b.StartTimer()
   102  
   103  	for i := 0; i < b.N; i++ {
   104  		if _, err := c.Do("PING"); err != nil {
   105  			b.Fatal(err)
   106  		}
   107  	}
   108  }
   109  
   110  func BenchmarkConnMux(b *testing.B) {
   111  	b.StopTimer()
   112  	c, err := redistest.Dial()
   113  	if err != nil {
   114  		b.Fatalf("error connection to database, %v", err)
   115  	}
   116  	m := redisx.NewConnMux(c)
   117  	defer m.Close()
   118  
   119  	b.StartTimer()
   120  
   121  	for i := 0; i < b.N; i++ {
   122  		c := m.Get()
   123  		if _, err := c.Do("PING"); err != nil {
   124  			b.Fatal(err)
   125  		}
   126  		c.Close()
   127  	}
   128  }
   129  
   130  func BenchmarkPool(b *testing.B) {
   131  	b.StopTimer()
   132  
   133  	p := redis.Pool{Dial: redistest.Dial, MaxIdle: 1}
   134  	defer p.Close()
   135  
   136  	// Fill the pool.
   137  	c := p.Get()
   138  	if err := c.Err(); err != nil {
   139  		b.Fatal(err)
   140  	}
   141  	c.Close()
   142  
   143  	b.StartTimer()
   144  
   145  	for i := 0; i < b.N; i++ {
   146  		c := p.Get()
   147  		if _, err := c.Do("PING"); err != nil {
   148  			b.Fatal(err)
   149  		}
   150  		c.Close()
   151  	}
   152  }
   153  
   154  const numConcurrent = 10
   155  
   156  func BenchmarkConnMuxConcurrent(b *testing.B) {
   157  	b.StopTimer()
   158  	c, err := redistest.Dial()
   159  	if err != nil {
   160  		b.Fatalf("error connection to database, %v", err)
   161  	}
   162  	defer c.Close()
   163  
   164  	m := redisx.NewConnMux(c)
   165  
   166  	var wg sync.WaitGroup
   167  	wg.Add(numConcurrent)
   168  
   169  	b.StartTimer()
   170  
   171  	for i := 0; i < numConcurrent; i++ {
   172  		go func() {
   173  			defer wg.Done()
   174  			for i := 0; i < b.N; i++ {
   175  				c := m.Get()
   176  				if _, err := c.Do("PING"); err != nil {
   177  					b.Fatal(err)
   178  				}
   179  				c.Close()
   180  			}
   181  		}()
   182  	}
   183  	wg.Wait()
   184  }
   185  
   186  func BenchmarkPoolConcurrent(b *testing.B) {
   187  	b.StopTimer()
   188  
   189  	p := redis.Pool{Dial: redistest.Dial, MaxIdle: numConcurrent}
   190  	defer p.Close()
   191  
   192  	// Fill the pool.
   193  	conns := make([]redis.Conn, numConcurrent)
   194  	for i := range conns {
   195  		c := p.Get()
   196  		if err := c.Err(); err != nil {
   197  			b.Fatal(err)
   198  		}
   199  		conns[i] = c
   200  	}
   201  	for _, c := range conns {
   202  		c.Close()
   203  	}
   204  
   205  	var wg sync.WaitGroup
   206  	wg.Add(numConcurrent)
   207  
   208  	b.StartTimer()
   209  
   210  	for i := 0; i < numConcurrent; i++ {
   211  		go func() {
   212  			defer wg.Done()
   213  			for i := 0; i < b.N; i++ {
   214  				c := p.Get()
   215  				if _, err := c.Do("PING"); err != nil {
   216  					b.Fatal(err)
   217  				}
   218  				c.Close()
   219  			}
   220  		}()
   221  	}
   222  	wg.Wait()
   223  }
   224  
   225  func BenchmarkPipelineConcurrency(b *testing.B) {
   226  	b.StopTimer()
   227  	c, err := redistest.Dial()
   228  	if err != nil {
   229  		b.Fatalf("error connection to database, %v", err)
   230  	}
   231  	defer c.Close()
   232  
   233  	var wg sync.WaitGroup
   234  	wg.Add(numConcurrent)
   235  
   236  	var pipeline textproto.Pipeline
   237  
   238  	b.StartTimer()
   239  
   240  	for i := 0; i < numConcurrent; i++ {
   241  		go func() {
   242  			defer wg.Done()
   243  			for i := 0; i < b.N; i++ {
   244  				id := pipeline.Next()
   245  				pipeline.StartRequest(id)
   246  				c.Send("PING")
   247  				c.Flush()
   248  				pipeline.EndRequest(id)
   249  				pipeline.StartResponse(id)
   250  				_, err := c.Receive()
   251  				if err != nil {
   252  					b.Fatal(err)
   253  				}
   254  				pipeline.EndResponse(id)
   255  			}
   256  		}()
   257  	}
   258  	wg.Wait()
   259  }
   260  

View as plain text