Skip to content

Commit 1f0ea0e

Browse files
abdellanindyakov
andauthored
feat(pubsub): introduce timeouts for Ping on channel.initHealthCheck (#3819)
* replace context.TODO with context.WithTimeout in channel.initHealthCheck before calling c.pubSub.Ping * fix(pubsub): create fresh timeout context for each health check * create context with timeout after lock acquisition * export pingTimeout and reconnectTimeout --------- Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com>
1 parent 5484b0b commit 1f0ea0e

1 file changed

Lines changed: 40 additions & 11 deletions

File tree

pubsub.go

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -659,25 +659,48 @@ func WithChannelSendTimeout(d time.Duration) ChannelOption {
659659
}
660660
}
661661

662+
// WithChannelPingTimeout specifies the timeout for the health-check ping.
663+
//
664+
// The default is 5 seconds.
665+
func WithChannelPingTimeout(d time.Duration) ChannelOption {
666+
return func(c *channel) {
667+
c.pingTimeout = d
668+
}
669+
}
670+
671+
// WithChannelReconnectTimeout specifies the timeout for reconnecting after
672+
// a failed health-check ping.
673+
//
674+
// The default is 10 seconds.
675+
func WithChannelReconnectTimeout(d time.Duration) ChannelOption {
676+
return func(c *channel) {
677+
c.reconnectTimeout = d
678+
}
679+
}
680+
662681
type channel struct {
663682
pubSub *PubSub
664683

665684
msgCh chan *Message
666685
allCh chan interface{}
667686
ping chan struct{}
668687

669-
chanSize int
670-
chanSendTimeout time.Duration
671-
checkInterval time.Duration
688+
chanSize int
689+
chanSendTimeout time.Duration
690+
checkInterval time.Duration
691+
pingTimeout time.Duration
692+
reconnectTimeout time.Duration
672693
}
673694

674695
func newChannel(pubSub *PubSub, opts ...ChannelOption) *channel {
675696
c := &channel{
676697
pubSub: pubSub,
677698

678-
chanSize: 100,
679-
chanSendTimeout: time.Minute,
680-
checkInterval: 3 * time.Second,
699+
chanSize: 100,
700+
chanSendTimeout: time.Minute,
701+
checkInterval: 3 * time.Second,
702+
pingTimeout: 5 * time.Second,
703+
reconnectTimeout: 10 * time.Second,
681704
}
682705
for _, opt := range opts {
683706
opt(c)
@@ -689,7 +712,6 @@ func newChannel(pubSub *PubSub, opts ...ChannelOption) *channel {
689712
}
690713

691714
func (c *channel) initHealthCheck() {
692-
ctx := context.TODO()
693715
c.ping = make(chan struct{}, 1)
694716

695717
go func() {
@@ -700,13 +722,20 @@ func (c *channel) initHealthCheck() {
700722
timer.Reset(c.checkInterval)
701723
select {
702724
case <-c.ping:
703-
if !timer.Stop() {
704-
<-timer.C
725+
select {
726+
case <-timer.C:
727+
default:
705728
}
706729
case <-timer.C:
707-
if pingErr := c.pubSub.Ping(ctx); pingErr != nil {
730+
ctx, cancel := context.WithTimeout(context.Background(), c.pingTimeout)
731+
pingErr := c.pubSub.Ping(ctx)
732+
cancel()
733+
734+
if pingErr != nil {
708735
c.pubSub.mu.Lock()
709-
c.pubSub.reconnect(ctx, pingErr)
736+
reconnectCtx, reconnectCancel := context.WithTimeout(context.Background(), c.reconnectTimeout)
737+
c.pubSub.reconnect(reconnectCtx, pingErr)
738+
reconnectCancel()
710739
c.pubSub.mu.Unlock()
711740
}
712741
case <-c.pubSub.exit:

0 commit comments

Comments
 (0)