github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/libkbfs/pinger.go (about)

     1  // Copyright 2017 Keybase Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD
     3  // license that can be found in the LICENSE file.
     4  
     5  package libkbfs
     6  
     7  import (
     8  	"sync"
     9  	"time"
    10  
    11  	"github.com/keybase/client/go/logger"
    12  	"golang.org/x/net/context"
    13  )
    14  
    15  // pinger is a helper type that calls a given function periodically.
    16  type pinger struct {
    17  	name    string
    18  	doPing  func(ctx context.Context)
    19  	timeout time.Duration
    20  	log     logger.Logger
    21  
    22  	tickerMu     sync.Mutex
    23  	tickerCancel context.CancelFunc
    24  }
    25  
    26  func (p *pinger) pingOnce(ctx context.Context) {
    27  	ctx, cancel := context.WithTimeout(ctx, p.timeout)
    28  	defer cancel()
    29  	p.doPing(ctx)
    30  }
    31  
    32  func (p *pinger) cancelTicker() {
    33  	p.tickerMu.Lock()
    34  	defer p.tickerMu.Unlock()
    35  
    36  	if p.tickerCancel != nil {
    37  		p.tickerCancel()
    38  		p.tickerCancel = nil
    39  	}
    40  }
    41  
    42  func (p *pinger) resetTicker(intervalSeconds int) {
    43  	p.tickerMu.Lock()
    44  	defer p.tickerMu.Unlock()
    45  
    46  	if p.tickerCancel != nil {
    47  		p.tickerCancel()
    48  		p.tickerCancel = nil
    49  	}
    50  
    51  	p.log.CDebugf(context.TODO(),
    52  		"%s: Starting new ping ticker with interval %d", p.name,
    53  		intervalSeconds)
    54  
    55  	var ctx context.Context
    56  	ctx, p.tickerCancel = context.WithCancel(context.Background())
    57  	go func() {
    58  		p.pingOnce(ctx)
    59  
    60  		if intervalSeconds <= 0 {
    61  			return
    62  		}
    63  
    64  		ticker := time.NewTicker(time.Duration(intervalSeconds) * time.Second)
    65  		for {
    66  			select {
    67  			case <-ticker.C:
    68  				p.pingOnce(ctx)
    69  
    70  			case <-ctx.Done():
    71  				p.log.CDebugf(ctx, "%s: stopping ping ticker", p.name)
    72  				ticker.Stop()
    73  				return
    74  			}
    75  		}
    76  	}()
    77  }