Source file src/cmd/vendor/golang.org/x/telemetry/internal/upload/date.go

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package upload
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"sync"
    11  	"time"
    12  
    13  	"golang.org/x/telemetry/internal/counter"
    14  	"golang.org/x/telemetry/internal/telemetry"
    15  )
    16  
    17  // time and date handling
    18  
    19  var distantPast = 21 * 24 * time.Hour
    20  
    21  // reports that are too old (21 days) are not uploaded
    22  func (u *uploader) tooOld(date string, uploadStartTime time.Time) bool {
    23  	t, err := time.Parse(telemetry.DateOnly, date)
    24  	if err != nil {
    25  		u.logger.Printf("tooOld: %v", err)
    26  		return false
    27  	}
    28  	age := uploadStartTime.Sub(t)
    29  	return age > distantPast
    30  }
    31  
    32  // counterDateSpan parses the counter file named fname and returns the (begin,
    33  // end) span recorded in its metadata, or an error if this data could not be
    34  // extracted.
    35  func (u *uploader) counterDateSpan(fname string) (begin, end time.Time, _ error) {
    36  	parsed, err := u.parseCountFile(fname)
    37  	if err != nil {
    38  		return time.Time{}, time.Time{}, err
    39  	}
    40  	timeBegin, ok := parsed.Meta["TimeBegin"]
    41  	if !ok {
    42  		return time.Time{}, time.Time{}, fmt.Errorf("missing counter metadata for TimeBegin")
    43  	}
    44  	begin, err = time.Parse(time.RFC3339, timeBegin)
    45  	if err != nil {
    46  		return time.Time{}, time.Time{}, fmt.Errorf("failed to parse TimeBegin: %v", err)
    47  	}
    48  	timeEnd, ok := parsed.Meta["TimeEnd"]
    49  	if !ok {
    50  		return time.Time{}, time.Time{}, fmt.Errorf("missing counter metadata for TimeEnd")
    51  	}
    52  	end, err = time.Parse(time.RFC3339, timeEnd)
    53  	if err != nil {
    54  		return time.Time{}, time.Time{}, fmt.Errorf("failed to parse TimeEnd: %v", err)
    55  	}
    56  	return begin, end, nil
    57  }
    58  
    59  // avoid parsing count files multiple times
    60  type parsedCache struct {
    61  	mu sync.Mutex
    62  	m  map[string]*counter.File
    63  }
    64  
    65  func (u *uploader) parseCountFile(fname string) (*counter.File, error) {
    66  	u.cache.mu.Lock()
    67  	defer u.cache.mu.Unlock()
    68  	if u.cache.m == nil {
    69  		u.cache.m = make(map[string]*counter.File)
    70  	}
    71  	if f, ok := u.cache.m[fname]; ok {
    72  		return f, nil
    73  	}
    74  	buf, err := os.ReadFile(fname)
    75  	if err != nil {
    76  		return nil, fmt.Errorf("parse ReadFile: %v for %s", err, fname)
    77  	}
    78  	f, err := counter.Parse(fname, buf)
    79  	if err != nil {
    80  
    81  		return nil, fmt.Errorf("parse Parse: %v for %s", err, fname)
    82  	}
    83  	u.cache.m[fname] = f
    84  	return f, nil
    85  }
    86  

View as plain text