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 }