mirror of https://github.com/go-redis/redis.git
Merge pull request #1253 from go-redis/feature/with-timeout
Add WithTimeout
This commit is contained in:
commit
a579d58c59
|
@ -169,6 +169,11 @@ func (opt *Options) init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (opt *Options) clone() *Options {
|
||||||
|
clone := *opt
|
||||||
|
return &clone
|
||||||
|
}
|
||||||
|
|
||||||
// ParseURL parses an URL into Options that can be used to connect to Redis.
|
// ParseURL parses an URL into Options that can be used to connect to Redis.
|
||||||
func ParseURL(redisURL string) (*Options, error) {
|
func ParseURL(redisURL string) (*Options, error) {
|
||||||
o := &Options{Network: "tcp"}
|
o := &Options{Network: "tcp"}
|
||||||
|
|
49
redis.go
49
redis.go
|
@ -137,6 +137,29 @@ type baseClient struct {
|
||||||
onClose func() error // hook called when client is closed
|
onClose func() error // hook called when client is closed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newBaseClient(opt *Options, connPool pool.Pooler) *baseClient {
|
||||||
|
return &baseClient{
|
||||||
|
opt: opt,
|
||||||
|
connPool: connPool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *baseClient) clone() *baseClient {
|
||||||
|
clone := *c
|
||||||
|
return &clone
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *baseClient) withTimeout(timeout time.Duration) *baseClient {
|
||||||
|
opt := c.opt.clone()
|
||||||
|
opt.ReadTimeout = timeout
|
||||||
|
opt.WriteTimeout = timeout
|
||||||
|
|
||||||
|
clone := c.clone()
|
||||||
|
clone.opt = opt
|
||||||
|
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
func (c *baseClient) String() string {
|
func (c *baseClient) String() string {
|
||||||
return fmt.Sprintf("Redis<%s db:%d>", c.getAddr(), c.opt.DB)
|
return fmt.Sprintf("Redis<%s db:%d>", c.getAddr(), c.opt.DB)
|
||||||
}
|
}
|
||||||
|
@ -481,7 +504,7 @@ func txPipelineReadQueued(rd *proto.Reader, cmds []Cmder) error {
|
||||||
// underlying connections. It's safe for concurrent use by multiple
|
// underlying connections. It's safe for concurrent use by multiple
|
||||||
// goroutines.
|
// goroutines.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
baseClient
|
*baseClient
|
||||||
cmdable
|
cmdable
|
||||||
hooks
|
hooks
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
@ -492,10 +515,7 @@ func NewClient(opt *Options) *Client {
|
||||||
opt.init()
|
opt.init()
|
||||||
|
|
||||||
c := Client{
|
c := Client{
|
||||||
baseClient: baseClient{
|
baseClient: newBaseClient(opt, newConnPool(opt)),
|
||||||
opt: opt,
|
|
||||||
connPool: newConnPool(opt),
|
|
||||||
},
|
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
}
|
}
|
||||||
c.cmdable = c.Process
|
c.cmdable = c.Process
|
||||||
|
@ -503,6 +523,19 @@ func NewClient(opt *Options) *Client {
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) clone() *Client {
|
||||||
|
clone := *c
|
||||||
|
clone.cmdable = clone.Process
|
||||||
|
clone.hooks.Lock()
|
||||||
|
return &clone
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) WithTimeout(timeout time.Duration) *Client {
|
||||||
|
clone := c.clone()
|
||||||
|
clone.baseClient = c.baseClient.withTimeout(timeout)
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) Context() context.Context {
|
func (c *Client) Context() context.Context {
|
||||||
return c.ctx
|
return c.ctx
|
||||||
}
|
}
|
||||||
|
@ -511,11 +544,9 @@ func (c *Client) WithContext(ctx context.Context) *Client {
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
panic("nil context")
|
panic("nil context")
|
||||||
}
|
}
|
||||||
clone := *c
|
clone := c.clone()
|
||||||
clone.cmdable = clone.Process
|
|
||||||
clone.hooks.Lock()
|
|
||||||
clone.ctx = ctx
|
clone.ctx = ctx
|
||||||
return &clone
|
return clone
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Conn() *Conn {
|
func (c *Client) Conn() *Conn {
|
||||||
|
|
|
@ -59,6 +59,10 @@ var _ = Describe("Client", func() {
|
||||||
client.Close()
|
client.Close()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("should Stringer", func() {
|
||||||
|
Expect(client.String()).To(Equal("Redis<:6380 db:15>"))
|
||||||
|
})
|
||||||
|
|
||||||
It("supports WithContext", func() {
|
It("supports WithContext", func() {
|
||||||
c, cancel := context.WithCancel(context.Background())
|
c, cancel := context.WithCancel(context.Background())
|
||||||
cancel()
|
cancel()
|
||||||
|
@ -67,8 +71,15 @@ var _ = Describe("Client", func() {
|
||||||
Expect(err).To(MatchError("context canceled"))
|
Expect(err).To(MatchError("context canceled"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should Stringer", func() {
|
It("supports WithTimeout", func() {
|
||||||
Expect(client.String()).To(Equal("Redis<:6380 db:15>"))
|
err := client.ClientPause(time.Second).Err()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
err = client.WithTimeout(10 * time.Millisecond).Ping().Err()
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
|
||||||
|
err = client.Ping().Err()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should ping", func() {
|
It("should ping", func() {
|
||||||
|
|
|
@ -94,14 +94,11 @@ func NewFailoverClient(failoverOpt *FailoverOptions) *Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
c := Client{
|
c := Client{
|
||||||
baseClient: baseClient{
|
baseClient: newBaseClient(opt, failover.Pool()),
|
||||||
opt: opt,
|
|
||||||
connPool: failover.Pool(),
|
|
||||||
onClose: failover.Close,
|
|
||||||
},
|
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
}
|
}
|
||||||
c.cmdable = c.Process
|
c.cmdable = c.Process
|
||||||
|
c.onClose = failover.Close
|
||||||
|
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue