Merge pull request #327 from go-redis/fix/opt-init

Rework Options initialisation.
This commit is contained in:
Vladimir Mihailenco 2016-06-05 14:29:20 +03:00
commit 58913a927b
5 changed files with 34 additions and 51 deletions

View File

@ -41,10 +41,7 @@ type ClusterClient struct {
// NewClusterClient returns a Redis Cluster client as described in // NewClusterClient returns a Redis Cluster client as described in
// http://redis.io/topics/cluster-spec. // http://redis.io/topics/cluster-spec.
func NewClusterClient(opt *ClusterOptions) *ClusterClient { func NewClusterClient(opt *ClusterOptions) *ClusterClient {
if opt.RouteByLatency { opt.init()
opt.ReadOnly = true
}
client := &ClusterClient{ client := &ClusterClient{
opt: opt, opt: opt,
nodes: make(map[string]*clusterNode), nodes: make(map[string]*clusterNode),
@ -246,7 +243,7 @@ func (c *ClusterClient) Process(cmd Cmder) {
var ask bool var ask bool
slot, node := c.cmdSlotAndNode(cmd) slot, node := c.cmdSlotAndNode(cmd)
for attempt := 0; attempt <= c.opt.getMaxRedirects(); attempt++ { for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ {
if attempt > 0 { if attempt > 0 {
cmd.reset() cmd.reset()
} }
@ -419,7 +416,7 @@ func (c *ClusterClient) pipelineExec(cmds []Cmder) error {
cmdsMap[node] = append(cmdsMap[node], cmd) cmdsMap[node] = append(cmdsMap[node], cmd)
} }
for attempt := 0; attempt <= c.opt.getMaxRedirects(); attempt++ { for attempt := 0; attempt <= c.opt.MaxRedirects; attempt++ {
failedCmds := make(map[*clusterNode][]Cmder) failedCmds := make(map[*clusterNode][]Cmder)
for node, cmds := range cmdsMap { for node, cmds := range cmdsMap {
@ -516,14 +513,16 @@ type ClusterOptions struct {
IdleCheckFrequency time.Duration IdleCheckFrequency time.Duration
} }
func (opt *ClusterOptions) getMaxRedirects() int { func (opt *ClusterOptions) init() {
if opt.MaxRedirects == -1 { if opt.MaxRedirects == -1 {
return 0 opt.MaxRedirects = 0
} else if opt.MaxRedirects == 0 {
opt.MaxRedirects = 16
} }
if opt.MaxRedirects == 0 {
return 16 if opt.RouteByLatency {
opt.ReadOnly = true
} }
return opt.MaxRedirects
} }
func (opt *ClusterOptions) clientOptions() *Options { func (opt *ClusterOptions) clientOptions() *Options {

View File

@ -58,61 +58,36 @@ type Options struct {
ReadOnly bool ReadOnly bool
} }
func (opt *Options) getNetwork() string { func (opt *Options) init() {
if opt.Network == "" { if opt.Network == "" {
return "tcp" opt.Network = "tcp"
} }
return opt.Network if opt.Dialer == nil {
} opt.Dialer = func() (net.Conn, error) {
return net.DialTimeout(opt.Network, opt.Addr, opt.DialTimeout)
func (opt *Options) getDialer() func() (net.Conn, error) {
if opt.Dialer != nil {
return opt.Dialer
}
return func() (net.Conn, error) {
return net.DialTimeout(opt.getNetwork(), opt.Addr, opt.getDialTimeout())
} }
} }
func (opt *Options) getPoolSize() int {
if opt.PoolSize == 0 { if opt.PoolSize == 0 {
return 10 opt.PoolSize = 10
} }
return opt.PoolSize
}
func (opt *Options) getDialTimeout() time.Duration {
if opt.DialTimeout == 0 { if opt.DialTimeout == 0 {
return 5 * time.Second opt.DialTimeout = 5 * time.Second
} }
return opt.DialTimeout
}
func (opt *Options) getPoolTimeout() time.Duration {
if opt.PoolTimeout == 0 { if opt.PoolTimeout == 0 {
return 1 * time.Second opt.PoolTimeout = 1 * time.Second
} }
return opt.PoolTimeout
}
func (opt *Options) getIdleTimeout() time.Duration {
return opt.IdleTimeout
}
func (opt *Options) getIdleCheckFrequency() time.Duration {
if opt.IdleCheckFrequency == 0 { if opt.IdleCheckFrequency == 0 {
return time.Minute opt.IdleCheckFrequency = time.Minute
} }
return opt.IdleCheckFrequency
} }
func newConnPool(opt *Options) *pool.ConnPool { func newConnPool(opt *Options) *pool.ConnPool {
return pool.NewConnPool( return pool.NewConnPool(
opt.getDialer(), opt.Dialer,
opt.getPoolSize(), opt.PoolSize,
opt.getPoolTimeout(), opt.PoolTimeout,
opt.getIdleTimeout(), opt.IdleTimeout,
opt.getIdleCheckFrequency(), opt.IdleCheckFrequency,
) )
} }

View File

@ -155,6 +155,7 @@ func newClient(opt *Options, pool pool.Pooler) *Client {
// NewClient returns a client to the Redis Server specified by Options. // NewClient returns a client to the Redis Server specified by Options.
func NewClient(opt *Options) *Client { func NewClient(opt *Options) *Client {
opt.init()
return newClient(opt, newConnPool(opt)) return newClient(opt, newConnPool(opt))
} }

View File

@ -39,6 +39,8 @@ type RingOptions struct {
IdleCheckFrequency time.Duration IdleCheckFrequency time.Duration
} }
func (opt *RingOptions) init() {}
func (opt *RingOptions) clientOptions() *Options { func (opt *RingOptions) clientOptions() *Options {
return &Options{ return &Options{
DB: opt.DB, DB: opt.DB,
@ -127,6 +129,7 @@ type Ring struct {
func NewRing(opt *RingOptions) *Ring { func NewRing(opt *RingOptions) *Ring {
const nreplicas = 100 const nreplicas = 100
opt.init()
ring := &Ring{ ring := &Ring{
opt: opt, opt: opt,
nreplicas: nreplicas, nreplicas: nreplicas,

View File

@ -64,12 +64,15 @@ func (opt *FailoverOptions) options() *Options {
// goroutines. // goroutines.
func NewFailoverClient(failoverOpt *FailoverOptions) *Client { func NewFailoverClient(failoverOpt *FailoverOptions) *Client {
opt := failoverOpt.options() opt := failoverOpt.options()
opt.init()
failover := &sentinelFailover{ failover := &sentinelFailover{
masterName: failoverOpt.MasterName, masterName: failoverOpt.MasterName,
sentinelAddrs: failoverOpt.SentinelAddrs, sentinelAddrs: failoverOpt.SentinelAddrs,
opt: opt, opt: opt,
} }
client := Client{ client := Client{
baseClient: baseClient{ baseClient: baseClient{
opt: opt, opt: opt,
@ -81,6 +84,7 @@ func NewFailoverClient(failoverOpt *FailoverOptions) *Client {
}, },
} }
client.cmdable.process = client.Process client.cmdable.process = client.Process
return &client return &client
} }
@ -92,6 +96,7 @@ type sentinelClient struct {
} }
func newSentinel(opt *Options) *sentinelClient { func newSentinel(opt *Options) *sentinelClient {
opt.init()
client := sentinelClient{ client := sentinelClient{
baseClient: baseClient{ baseClient: baseClient{
opt: opt, opt: opt,