Example #1
0
// 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.")
}
Example #2
0
// 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
}
Example #3
0
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
}
Example #4
0
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))
	}
}