86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
![]() |
// Copyright 2023 The Go Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package upload
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"sync"
|
||
|
"time"
|
||
|
|
||
|
"golang.org/x/telemetry/internal/counter"
|
||
|
"golang.org/x/telemetry/internal/telemetry"
|
||
|
)
|
||
|
|
||
|
// time and date handling
|
||
|
|
||
|
var distantPast = 21 * 24 * time.Hour
|
||
|
|
||
|
// reports that are too old (21 days) are not uploaded
|
||
|
func (u *uploader) tooOld(date string, uploadStartTime time.Time) bool {
|
||
|
t, err := time.Parse(telemetry.DateOnly, date)
|
||
|
if err != nil {
|
||
|
u.logger.Printf("tooOld: %v", err)
|
||
|
return false
|
||
|
}
|
||
|
age := uploadStartTime.Sub(t)
|
||
|
return age > distantPast
|
||
|
}
|
||
|
|
||
|
// counterDateSpan parses the counter file named fname and returns the (begin,
|
||
|
// end) span recorded in its metadata, or an error if this data could not be
|
||
|
// extracted.
|
||
|
func (u *uploader) counterDateSpan(fname string) (begin, end time.Time, _ error) {
|
||
|
parsed, err := u.parseCountFile(fname)
|
||
|
if err != nil {
|
||
|
return time.Time{}, time.Time{}, err
|
||
|
}
|
||
|
timeBegin, ok := parsed.Meta["TimeBegin"]
|
||
|
if !ok {
|
||
|
return time.Time{}, time.Time{}, fmt.Errorf("missing counter metadata for TimeBegin")
|
||
|
}
|
||
|
begin, err = time.Parse(time.RFC3339, timeBegin)
|
||
|
if err != nil {
|
||
|
return time.Time{}, time.Time{}, fmt.Errorf("failed to parse TimeBegin: %v", err)
|
||
|
}
|
||
|
timeEnd, ok := parsed.Meta["TimeEnd"]
|
||
|
if !ok {
|
||
|
return time.Time{}, time.Time{}, fmt.Errorf("missing counter metadata for TimeEnd")
|
||
|
}
|
||
|
end, err = time.Parse(time.RFC3339, timeEnd)
|
||
|
if err != nil {
|
||
|
return time.Time{}, time.Time{}, fmt.Errorf("failed to parse TimeEnd: %v", err)
|
||
|
}
|
||
|
return begin, end, nil
|
||
|
}
|
||
|
|
||
|
// avoid parsing count files multiple times
|
||
|
type parsedCache struct {
|
||
|
mu sync.Mutex
|
||
|
m map[string]*counter.File
|
||
|
}
|
||
|
|
||
|
func (u *uploader) parseCountFile(fname string) (*counter.File, error) {
|
||
|
u.cache.mu.Lock()
|
||
|
defer u.cache.mu.Unlock()
|
||
|
if u.cache.m == nil {
|
||
|
u.cache.m = make(map[string]*counter.File)
|
||
|
}
|
||
|
if f, ok := u.cache.m[fname]; ok {
|
||
|
return f, nil
|
||
|
}
|
||
|
buf, err := os.ReadFile(fname)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("parse ReadFile: %v for %s", err, fname)
|
||
|
}
|
||
|
f, err := counter.Parse(fname, buf)
|
||
|
if err != nil {
|
||
|
|
||
|
return nil, fmt.Errorf("parse Parse: %v for %s", err, fname)
|
||
|
}
|
||
|
u.cache.m[fname] = f
|
||
|
return f, nil
|
||
|
}
|