From ffcef936f1639d6a23ed3dafbfff61243af3643e Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Wed, 9 Oct 2024 12:53:56 -0700 Subject: [PATCH] Reuse timers instead of time.After in loops Reusing a timer repeatedly results in less GC than time.After in each loop iteration. Closes #122 --- bitswap/network/ipfs_impl.go | 5 ++++- bootstrap/bootstrap.go | 6 +++++- mfs/repub.go | 11 ++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/bitswap/network/ipfs_impl.go b/bitswap/network/ipfs_impl.go index 7acc3abcc..f01adb996 100644 --- a/bitswap/network/ipfs_impl.go +++ b/bitswap/network/ipfs_impl.go @@ -179,10 +179,13 @@ func (s *streamMessageSender) multiAttempt(ctx context.Context, fn func() error) return err } + timer := time.NewTimer(s.opts.SendErrorBackoff) + defer timer.Stop() + select { case <-ctx.Done(): return ctx.Err() - case <-time.After(s.opts.SendErrorBackoff): + case <-timer.C: // wait a short time in case disconnect notifications are still propagating log.Infof("send message to %s failed but context was not Done: %s", s.to, err) } diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 303405f14..28b004559 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -304,15 +304,19 @@ func peersConnect(ctx context.Context, ph host.Host, availablePeers []peer.AddrI ctx, cancel := context.WithCancel(ctx) defer cancel() go func() { + timer := time.NewTimer(time.Second) + defer timer.Stop() + for { select { case <-ctx.Done(): return - case <-time.After(1 * time.Second): + case <-timer.C: if int(atomic.LoadUint64(&connected)) >= needed { cancel() return } + timer.Reset(time.Second) } } }() diff --git a/mfs/repub.go b/mfs/repub.go index 463810414..3525d919c 100644 --- a/mfs/repub.go +++ b/mfs/repub.go @@ -169,18 +169,27 @@ func (rp *Republisher) Run(lastPublished cid.Cid) { // 2. If we have a value to publish, publish it now. if toPublish.Defined() { + var timer *time.Timer for { err := rp.pubfunc(rp.ctx, toPublish) if err == nil { break } + + if timer == nil { + timer = time.NewTimer(rp.RetryTimeout) + defer timer.Stop() + } else { + timer.Reset(rp.RetryTimeout) + } + // Keep retrying until we succeed or we abort. // TODO(steb): We could try pulling new values // off `update` but that's not critical (and // complicates this code a bit). We'll pull off // a new value on the next loop through. select { - case <-time.After(rp.RetryTimeout): + case <-timer.C: case <-rp.ctx.Done(): return }