// OpenRedisContainerConnection is supported for legacy reasons. Don't use it. func OpenRedisContainerConnection(tries int, delay time.Duration) (c ContainerID, client *redis.Client, err error) { c, ip, port, err := SetupRedisContainer() if err != nil { return c, nil, fmt.Errorf("Could not set up Redis container: %v", err) } for try := 0; try <= tries; try++ { time.Sleep(delay) url := fmt.Sprintf("%s:%d", ip, port) log.Printf("Try %d: Connecting %s", try, url) client, err := redis.DialTimeout("tcp", url, 10*time.Second) if err == nil { log.Printf("Try %d: Successfully connected to %v", try, client.Addr) return c, client, nil } log.Printf("Try %d: Could not set up Redis container: %v", try, err) } return c, nil, errors.New("Could not set up Redis container.") }
// NewWithOpts is the same as NewCluster, but with more fine-tuned // configuration options. See Opts for more available options func NewWithOpts(o Opts) (*Cluster, error) { if o.PoolSize == 0 { o.PoolSize = 10 } if o.PoolThrottle == 0 { o.PoolThrottle = 500 * time.Millisecond } if o.ResetThrottle == 0 { o.ResetThrottle = 500 * time.Millisecond } if o.Dialer == nil { o.Dialer = func(_, addr string) (*redis.Client, error) { return redis.DialTimeout("tcp", addr, o.Timeout) } } c := Cluster{ o: o, mapping: mapping{}, pools: map[string]*pool.Pool{}, poolThrottles: map[string]<-chan time.Time{}, callCh: make(chan func(*Cluster)), stopCh: make(chan struct{}), MissCh: make(chan struct{}), ChangeCh: make(chan struct{}), } initialPool, err := c.newPool(o.Addr, true) if err != nil { return nil, err } c.pools[o.Addr] = initialPool go c.spin() if err := c.Reset(); err != nil { return nil, err } return &c, nil }
func (c *Cluster) newPool(addr string, clearThrottle bool) (*pool.Pool, error) { if clearThrottle { delete(c.poolThrottles, addr) } else if throttle, ok := c.poolThrottles[addr]; ok { select { case <-throttle: delete(c.poolThrottles, addr) default: return nil, fmt.Errorf("newPool(%s) throttled", addr) } } df := func(network, addr string) (*redis.Client, error) { return redis.DialTimeout(network, addr, c.o.Timeout) } p, err := pool.NewCustom("tcp", addr, c.o.PoolSize, df) if err != nil { c.poolThrottles[addr] = time.After(c.o.PoolThrottle) return nil, err } return p, err }
func TestPSubscribe(t *testing.T) { pub, err := redis.DialTimeout("tcp", "localhost:6379", time.Duration(10)*time.Second) if err != nil { t.Fatal(err) } client, err := redis.DialTimeout("tcp", "localhost:6379", time.Duration(10)*time.Second) if err != nil { t.Fatal(err) } sub := NewSubClient(client) pattern := "patternThen*" message := "Hello, World!" sr := sub.PSubscribe(pattern) if sr.Err != nil { t.Fatal(sr.Err) } if sr.Type != Subscribe { t.Fatal("Did not receive a subscribe reply") } if sr.SubCount != 1 { t.Fatal(fmt.Sprintf("Unexpected subscription count, Expected: 0, Found: %d", sr.SubCount)) } r := pub.Cmd("PUBLISH", "patternThenHello", message) if r.Err != nil { t.Fatal(r.Err) } subChan := make(chan *SubResp) go func() { subChan <- sub.Receive() }() select { case sr = <-subChan: case <-time.After(time.Duration(10) * time.Second): t.Fatal("Took too long to Receive message") } if sr.Err != nil { t.Fatal(sr.Err) } if sr.Type != Message { t.Fatal("Did not receive a message reply") } if sr.Pattern != pattern { t.Fatal(fmt.Sprintf("Did not recieve expected pattern '%s', instead got: '%s'", pattern, sr.Pattern)) } if sr.Message != message { t.Fatal(fmt.Sprintf("Did not recieve expected message '%s', instead got: '%s'", message, sr.Message)) } sr = sub.PUnsubscribe(pattern) if sr.Err != nil { t.Fatal(sr.Err) } if sr.Type != Unsubscribe { t.Fatal("Did not receive a unsubscribe reply") } if sr.SubCount != 0 { t.Fatal(fmt.Sprintf("Unexpected subscription count, Expected: 0, Found: %d", sr.SubCount)) } }