feat: cache notices to reduce frequency of upgrade notifications (#1592)

* feat: cache notices to reduce frequency of upgrade notifications

* fix: reduce WriteFile permissions

* fix: remove reference to deprecated lib

* fix: handle HTTP status 304
This commit is contained in:
Casey Lee 2023-02-01 16:54:57 -08:00 committed by GitHub
parent 787388daf5
commit 42b9b73d38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 61 additions and 1 deletions

View File

@ -6,9 +6,12 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"path/filepath"
"runtime" "runtime"
"strings"
"time" "time"
"github.com/mitchellh/go-homedir"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@ -73,14 +76,37 @@ func getVersionNotices(version string) []Notice {
noticeURL.RawQuery = query.Encode() noticeURL.RawQuery = query.Encode()
resp, err := http.Get(noticeURL.String()) client := &http.Client{}
req, err := http.NewRequest("GET", noticeURL.String(), nil)
if err != nil { if err != nil {
log.Debug(err) log.Debug(err)
return nil return nil
} }
etag := loadNoticesEtag()
if etag != "" {
log.Debugf("Conditional GET for notices etag=%s", etag)
req.Header.Set("If-None-Match", etag)
}
resp, err := client.Do(req)
if err != nil {
log.Debug(err)
return nil
}
newEtag := resp.Header.Get("Etag")
if newEtag != "" {
log.Debugf("Saving notices etag=%s", newEtag)
saveNoticesEtag(newEtag)
}
defer resp.Body.Close() defer resp.Body.Close()
notices := []Notice{} notices := []Notice{}
if resp.StatusCode == 304 {
log.Debug("No new notices")
return nil
}
if err := json.NewDecoder(resp.Body).Decode(&notices); err != nil { if err := json.NewDecoder(resp.Body).Decode(&notices); err != nil {
log.Debug(err) log.Debug(err)
return nil return nil
@ -88,3 +114,37 @@ func getVersionNotices(version string) []Notice {
return notices return notices
} }
func loadNoticesEtag() string {
p := etagPath()
content, err := os.ReadFile(p)
if err != nil {
log.Debugf("Unable to load etag from %s: %e", p, err)
}
return strings.TrimSuffix(string(content), "\n")
}
func saveNoticesEtag(etag string) {
p := etagPath()
err := os.WriteFile(p, []byte(strings.TrimSuffix(etag, "\n")), 0600)
if err != nil {
log.Debugf("Unable to save etag to %s: %e", p, err)
}
}
func etagPath() string {
var xdgCache string
var ok bool
if xdgCache, ok = os.LookupEnv("XDG_CACHE_HOME"); !ok || xdgCache == "" {
if home, err := homedir.Dir(); err == nil {
xdgCache = filepath.Join(home, ".cache")
} else if xdgCache, err = filepath.Abs("."); err != nil {
log.Fatal(err)
}
}
dir := filepath.Join(xdgCache, "act")
if err := os.MkdirAll(dir, 0777); err != nil {
log.Fatal(err)
}
return filepath.Join(dir, ".notices.etag")
}