mirror of
https://github.com/redis/go-redis.git
synced 2025-10-18 22:08:50 +03:00
better conn usable timeout
This commit is contained in:
@@ -13,10 +13,18 @@ import (
|
|||||||
// - reAuth: a function that takes the new credentials and returns an error if any.
|
// - reAuth: a function that takes the new credentials and returns an error if any.
|
||||||
// - onErr: a function that takes an error and handles it.
|
// - onErr: a function that takes an error and handles it.
|
||||||
// - conn: the connection to re-authenticate.
|
// - conn: the connection to re-authenticate.
|
||||||
|
// - checkUsableTimeout: the timeout to wait for the connection to be usable - default is 1 second.
|
||||||
type ConnReAuthCredentialsListener struct {
|
type ConnReAuthCredentialsListener struct {
|
||||||
|
// reAuth is called when the credentials are updated.
|
||||||
reAuth func(conn *pool.Conn, credentials Credentials) error
|
reAuth func(conn *pool.Conn, credentials Credentials) error
|
||||||
|
// onErr is called when an error occurs.
|
||||||
onErr func(conn *pool.Conn, err error)
|
onErr func(conn *pool.Conn, err error)
|
||||||
|
// conn is the connection to re-authenticate.
|
||||||
conn *pool.Conn
|
conn *pool.Conn
|
||||||
|
// checkUsableTimeout is the timeout to wait for the connection to be usable
|
||||||
|
// when the credentials are updated.
|
||||||
|
// default is 1 second
|
||||||
|
checkUsableTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnNext is called when the credentials are updated.
|
// OnNext is called when the credentials are updated.
|
||||||
@@ -32,7 +40,9 @@ func (c *ConnReAuthCredentialsListener) OnNext(credentials Credentials) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
timeout := time.After(1 * time.Second)
|
|
||||||
|
// this hard-coded timeout is not ideal
|
||||||
|
timeout := time.After(c.checkUsableTimeout)
|
||||||
// wait for the connection to be usable
|
// wait for the connection to be usable
|
||||||
// this is important because the connection pool may be in the process of reconnecting the connection
|
// this is important because the connection pool may be in the process of reconnecting the connection
|
||||||
// and we don't want to interfere with that process
|
// and we don't want to interfere with that process
|
||||||
@@ -68,6 +78,11 @@ func (c *ConnReAuthCredentialsListener) OnError(err error) {
|
|||||||
c.onErr(c.conn, err)
|
c.onErr(c.conn, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetCheckUsableTimeout sets the timeout for the connection to be usable.
|
||||||
|
func (c *ConnReAuthCredentialsListener) SetCheckUsableTimeout(timeout time.Duration) {
|
||||||
|
c.checkUsableTimeout = timeout
|
||||||
|
}
|
||||||
|
|
||||||
// NewConnReAuthCredentialsListener creates a new ConnReAuthCredentialsListener.
|
// NewConnReAuthCredentialsListener creates a new ConnReAuthCredentialsListener.
|
||||||
// Implements the auth.CredentialsListener interface.
|
// Implements the auth.CredentialsListener interface.
|
||||||
func NewConnReAuthCredentialsListener(conn *pool.Conn, reAuth func(conn *pool.Conn, credentials Credentials) error, onErr func(conn *pool.Conn, err error)) *ConnReAuthCredentialsListener {
|
func NewConnReAuthCredentialsListener(conn *pool.Conn, reAuth func(conn *pool.Conn, credentials Credentials) error, onErr func(conn *pool.Conn, err error)) *ConnReAuthCredentialsListener {
|
||||||
@@ -75,8 +90,10 @@ func NewConnReAuthCredentialsListener(conn *pool.Conn, reAuth func(conn *pool.Co
|
|||||||
conn: conn,
|
conn: conn,
|
||||||
reAuth: reAuth,
|
reAuth: reAuth,
|
||||||
onErr: onErr,
|
onErr: onErr,
|
||||||
|
checkUsableTimeout: 1 * time.Second,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Ensure ConnReAuthCredentialsListener implements the CredentialsListener interface.
|
// Ensure ConnReAuthCredentialsListener implements the CredentialsListener interface.
|
||||||
var _ CredentialsListener = (*ConnReAuthCredentialsListener)(nil)
|
var _ CredentialsListener = (*ConnReAuthCredentialsListener)(nil)
|
||||||
|
6
redis.go
6
redis.go
@@ -319,6 +319,12 @@ func (c *baseClient) connReAuthCredentialsListener(poolCn *pool.Conn) (auth.Cred
|
|||||||
c.reAuthConnection(),
|
c.reAuthConnection(),
|
||||||
c.onAuthenticationErr(),
|
c.onAuthenticationErr(),
|
||||||
)
|
)
|
||||||
|
// main case where the connection can be stuck in the listener for a long time is when we have a handoff
|
||||||
|
// so we set the checkUsableTimeout to the handoff timeout if maintnotifications are enabled
|
||||||
|
// the default timeout if no maintnotifications config is provided is 1 second
|
||||||
|
if c.opt.MaintNotificationsConfig != nil && c.opt.MaintNotificationsConfig.Mode != maintnotifications.ModeDisabled {
|
||||||
|
newCredListener.SetCheckUsableTimeout(c.opt.MaintNotificationsConfig.HandoffTimeout)
|
||||||
|
}
|
||||||
c.credListeners[poolCn] = newCredListener
|
c.credListeners[poolCn] = newCredListener
|
||||||
return newCredListener, func() {
|
return newCredListener, func() {
|
||||||
c.removeCredListener(poolCn)
|
c.removeCredListener(poolCn)
|
||||||
|
Reference in New Issue
Block a user