github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/reporter_simple.go (about)

     1  // Copyright 2016 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  	"runtime"
     9  	"sync"
    10  
    11  	"golang.org/x/net/context"
    12  
    13  	"github.com/keybase/client/go/kbfs/tlf"
    14  	"github.com/keybase/client/go/protocol/keybase1"
    15  )
    16  
    17  // ReporterSimple remembers the last maxErrors errors, or all errors
    18  // if maxErrors < 1.
    19  type ReporterSimple struct {
    20  	clock          Clock
    21  	maxErrors      int
    22  	currErrorIndex int
    23  	filledOnce     bool
    24  	// errors is a circular buffer when maxErrors >= 1
    25  	errors []ReportedError
    26  	lock   sync.RWMutex // protects everything
    27  }
    28  
    29  // NewReporterSimple creates a new ReporterSimple.
    30  func NewReporterSimple(clock Clock, maxErrors int) *ReporterSimple {
    31  	rs := &ReporterSimple{
    32  		clock:          clock,
    33  		maxErrors:      maxErrors,
    34  		currErrorIndex: -1,
    35  	}
    36  
    37  	if maxErrors >= 1 {
    38  		rs.errors = make([]ReportedError, maxErrors)
    39  	}
    40  
    41  	return rs
    42  }
    43  
    44  // ReportErr implements the Reporter interface for ReporterSimple.
    45  func (r *ReporterSimple) ReportErr(ctx context.Context,
    46  	_ tlf.CanonicalName, _ tlf.Type, _ ErrorModeType, err error) {
    47  	r.lock.Lock()
    48  	defer r.lock.Unlock()
    49  
    50  	stack := make([]uintptr, 20)
    51  	n := runtime.Callers(2, stack)
    52  	re := ReportedError{
    53  		Time:  r.clock.Now(),
    54  		Error: err,
    55  		Stack: stack[:n],
    56  	}
    57  	r.currErrorIndex++
    58  	if r.maxErrors < 1 {
    59  		r.errors = append(r.errors, re)
    60  	} else {
    61  		if r.currErrorIndex == r.maxErrors {
    62  			r.currErrorIndex = 0
    63  			r.filledOnce = true
    64  		}
    65  		r.errors[r.currErrorIndex] = re
    66  	}
    67  
    68  }
    69  
    70  // AllKnownErrors implements the Reporter interface for ReporterSimple.
    71  func (r *ReporterSimple) AllKnownErrors() []ReportedError {
    72  	r.lock.RLock()
    73  	defer r.lock.RUnlock()
    74  
    75  	if !r.filledOnce {
    76  		// deep copy since r.errors shouldn't be read without the lock.
    77  		errors := make([]ReportedError, r.currErrorIndex+1)
    78  		copy(errors, r.errors[:r.currErrorIndex+1])
    79  		return errors
    80  	}
    81  
    82  	errors := make([]ReportedError, r.maxErrors)
    83  	s := r.currErrorIndex + 1
    84  	t := r.maxErrors - s
    85  	copy(errors[:t], r.errors[s:])
    86  	copy(errors[t:], r.errors[:s])
    87  	return errors
    88  }
    89  
    90  // OnlineStatusChanged implements the Reporter interface for ReporterSimple.
    91  func (r *ReporterSimple) OnlineStatusChanged(_ context.Context, online bool) {
    92  	// ignore notifications
    93  }
    94  
    95  // Notify implements the Reporter interface for ReporterSimple.
    96  func (r *ReporterSimple) Notify(_ context.Context, _ *keybase1.FSNotification) {
    97  	// ignore notifications
    98  }
    99  
   100  // NotifyPathUpdated implements the Reporter interface for ReporterSimple.
   101  func (r *ReporterSimple) NotifyPathUpdated(_ context.Context, _ string) {
   102  	// ignore notifications
   103  }
   104  
   105  // NotifySyncStatus implements the Reporter interface for ReporterSimple.
   106  func (r *ReporterSimple) NotifySyncStatus(_ context.Context,
   107  	_ *keybase1.FSPathSyncStatus) {
   108  	// ignore notifications
   109  }
   110  
   111  // NotifyFavoritesChanged implements the Reporter interface for
   112  // ReporterSimple.
   113  func (r *ReporterSimple) NotifyFavoritesChanged(_ context.Context) {
   114  	// ignore notifications
   115  }
   116  
   117  // NotifyOverallSyncStatus implements the Reporter interface for
   118  // ReporterSimple.
   119  func (r *ReporterSimple) NotifyOverallSyncStatus(
   120  	_ context.Context, _ keybase1.FolderSyncStatus) {
   121  	// ignore notifications
   122  }
   123  
   124  // Shutdown implements the Reporter interface for ReporterSimple.
   125  func (r *ReporterSimple) Shutdown() {
   126  
   127  }