src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

date.go (2283B)


      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 }