示例#1
0
func NewRedisStorage(address string, db int, pass, mrshlerStr string, maxConns int) (*RedisStorage, error) {
	df := func(network, addr string) (*redis.Client, error) {
		client, err := redis.Dial(network, addr)
		if err != nil {
			return nil, err
		}
		if len(pass) != 0 {
			if err = client.Cmd("AUTH", pass).Err; err != nil {
				client.Close()
				return nil, err
			}
		}
		if db != 0 {
			if err = client.Cmd("SELECT", db).Err; err != nil {
				client.Close()
				return nil, err
			}
		}
		return client, nil
	}
	p, err := pool.NewCustom("tcp", address, maxConns, df)
	if err != nil {
		return nil, err
	}
	var mrshler Marshaler
	if mrshlerStr == utils.MSGPACK {
		mrshler = NewCodecMsgpackMarshaler()
	} else if mrshlerStr == utils.JSON {
		mrshler = new(JSONMarshaler)
	} else {
		return nil, fmt.Errorf("Unsupported marshaler: %v", mrshlerStr)
	}
	return &RedisStorage{db: p, ms: mrshler}, nil
}
示例#2
0
func (config *PoolConnectionConfig) PoolCreation(maxConns int) (*pool.Pool, error) {
	p, err := pool.NewCustom("tcp", config.address, maxConns, config.DialFunction)
	if err != nil {
		return nil, err
	}
	return p, nil
}
示例#3
0
func NewRedisProvider(network, addr, auth string, idleConns int) (*RedisProvider, error) {
	df := func(n, a string) (*redis.Client, error) {
		c, err := redis.Dial(n, a)
		if err != nil {
			return nil, err
		}

		if err = c.Cmd("AUTH", auth).Err; err != nil {
			c.Close()
			return nil, err
		}

		return c, nil
	}

	p, err := rPool.NewCustom(network, addr, idleConns, df)
	if err != nil {
		return nil, err
	}

	rp := &RedisProvider{
		Pool: p,
	}

	return rp, nil
}
示例#4
0
// NewClientCustom is the same as NewClient, except it takes in a DialFunc which
// will be used to create all new connections to the master instances. This can
// be used to implement authentication, custom timeouts, etc...
func NewClientCustom(
	network, address string, poolSize int, df DialFunc, names ...string,
) (
	*Client, error,
) {

	// We use this to fetch initial details about masters before we upgrade it
	// to a pubsub client
	client, err := redis.Dial(network, address)
	if err != nil {
		return nil, &ClientError{err: err}
	}

	masterPools := map[string]*pool.Pool{}
	for _, name := range names {
		r := client.Cmd("SENTINEL", "MASTER", name)
		l, err := r.List()
		if err != nil {
			return nil, &ClientError{err: err, SentinelErr: true}
		}
		addr := l[3] + ":" + l[5]
		pool, err := pool.NewCustom("tcp", addr, poolSize, (pool.DialFunc)(df))
		if err != nil {
			return nil, &ClientError{err: err}
		}
		masterPools[name] = pool
	}

	subClient := pubsub.NewSubClient(client)
	r := subClient.Subscribe("+switch-master")
	if r.Err != nil {
		return nil, &ClientError{err: r.Err, SentinelErr: true}
	}

	c := &Client{
		poolSize:       poolSize,
		masterPools:    masterPools,
		subClient:      subClient,
		dialFunc:       (pool.DialFunc)(df),
		getCh:          make(chan *getReq),
		putCh:          make(chan *putReq),
		closeCh:        make(chan struct{}),
		alwaysErrCh:    make(chan *ClientError),
		switchMasterCh: make(chan *switchMaster),
	}

	go c.subSpin()
	go c.spin()
	return c, nil
}
示例#5
0
func (c *Client) spin() {
	for {
		select {
		case req := <-c.getCh:
			if c.alwaysErr != nil {
				req.retCh <- &getReqRet{nil, c.alwaysErr}
				continue
			}
			pool, ok := c.masterPools[req.name]
			if !ok {
				err := errors.New("unknown name: " + req.name)
				req.retCh <- &getReqRet{nil, &ClientError{err: err}}
				continue
			}
			conn, err := pool.Get()
			if err != nil {
				req.retCh <- &getReqRet{nil, &ClientError{err: err}}
				continue
			}
			req.retCh <- &getReqRet{conn, nil}

		case req := <-c.putCh:
			if pool, ok := c.masterPools[req.name]; ok {
				pool.Put(req.conn)
			}

		case err := <-c.alwaysErrCh:
			c.alwaysErr = err

		case sm := <-c.switchMasterCh:
			if p, ok := c.masterPools[sm.name]; ok {
				p.Empty()
				p, _ = pool.NewCustom("tcp", sm.addr, c.poolSize, c.dialFunc)
				c.masterPools[sm.name] = p
			}

		case <-c.closeCh:
			for name := range c.masterPools {
				c.masterPools[name].Empty()
			}
			c.subClient.Client.Close()
			close(c.getCh)
			close(c.putCh)
			return
		}
	}
}
示例#6
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 c.o.Dialer(network, addr)
	}
	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
}
示例#7
0
func NewRedisStorage(address string, db int, pass, mrshlerStr string, maxConns int, cacheDumpDir string, loadHistorySize int) (*RedisStorage, error) {
	df := func(network, addr string) (*redis.Client, error) {
		client, err := redis.Dial(network, addr)
		if err != nil {
			return nil, err
		}
		if len(pass) != 0 {
			if err = client.Cmd("AUTH", pass).Err; err != nil {
				client.Close()
				return nil, err
			}
		}
		if db != 0 {
			if err = client.Cmd("SELECT", db).Err; err != nil {
				client.Close()
				return nil, err
			}
		}
		return client, nil
	}
	p, err := pool.NewCustom("tcp", address, maxConns, df)
	if err != nil {
		return nil, err
	}
	var mrshler Marshaler
	if mrshlerStr == utils.MSGPACK {
		mrshler = NewCodecMsgpackMarshaler()
	} else if mrshlerStr == utils.JSON {
		mrshler = new(JSONMarshaler)
	} else {
		return nil, fmt.Errorf("Unsupported marshaler: %v", mrshlerStr)
	}
	if cacheDumpDir != "" {
		if err := CacheSetDumperPath(cacheDumpDir); err != nil {
			utils.Logger.Info("<cache dumper> init error: " + err.Error())
		}
	}
	return &RedisStorage{db: p, ms: mrshler, cacheDumpDir: cacheDumpDir, loadHistorySize: loadHistorySize}, nil
}