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 }