github.com/Rookout/GoSDK@v0.1.48/pkg/com_ws/simple_backoff.go (about)

     1  package com_ws
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"github.com/Rookout/GoSDK/pkg/config"
     8  	"github.com/Rookout/GoSDK/pkg/logger"
     9  )
    10  
    11  type Backoff interface {
    12  	AfterConnect()
    13  	AfterDisconnect(context.Context)
    14  }
    15  
    16  type backoff struct {
    17  	connectTime time.Time
    18  	connected   bool
    19  	nextBackoff time.Duration
    20  }
    21  
    22  func NewBackoff() *backoff {
    23  	return &backoff{
    24  		nextBackoff: config.BackoffConfig().DefaultBackoff,
    25  	}
    26  }
    27  
    28  func (b *backoff) AfterConnect() {
    29  	b.connectTime = time.Now()
    30  	b.connected = true
    31  }
    32  
    33  func (b *backoff) AfterDisconnect(ctx context.Context) {
    34  	if b.connected && time.Since(b.connectTime) > config.BackoffConfig().ResetBackoffTimeout {
    35  		b.reset()
    36  	}
    37  
    38  	b.connected = false
    39  	logger.Logger().Debugf("Backing off %g seconds\n", b.nextBackoff.Seconds())
    40  	timer := time.NewTimer(b.nextBackoff)
    41  	defer timer.Stop()
    42  	select {
    43  	case <-timer.C:
    44  	case <-ctx.Done():
    45  		return
    46  	}
    47  
    48  	b.nextBackoff *= 2
    49  	maxBackoff := config.BackoffConfig().MaxBackoff
    50  	if maxBackoff != 0 && b.nextBackoff > maxBackoff {
    51  		b.nextBackoff = maxBackoff
    52  	}
    53  }
    54  
    55  func (b *backoff) reset() {
    56  	b.nextBackoff = config.BackoffConfig().DefaultBackoff
    57  }