github.com/web-platform-tests/wpt.fyi@v0.0.0-20240530210107-70cf978996f1/api/metadata_cache.go (about) 1 // Copyright 2020 The WPT Dashboard Project. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package api 6 7 import ( 8 "context" 9 "errors" 10 "net/http" 11 "time" 12 13 "github.com/google/go-github/v47/github" 14 "github.com/web-platform-tests/wpt.fyi/shared" 15 ) 16 17 const metadataCacheKey = "WPT-METADATA" 18 const metadataCacheExpiry = time.Minute * 10 19 20 type webappMetadataFetcher struct { 21 ctx context.Context // nolint:containedctx // TODO: Fix containedctx lint error 22 httpClient *http.Client 23 gitHubClient *github.Client 24 forceUpdate bool 25 } 26 27 func (f webappMetadataFetcher) Fetch() (sha *string, res map[string][]byte, err error) { 28 log := shared.GetLogger(f.ctx) 29 mCache := shared.NewJSONObjectCache(f.ctx, shared.NewRedisReadWritable(f.ctx, metadataCacheExpiry)) 30 if !f.forceUpdate { 31 sha, metadataMap, err := getMetadataFromRedis(mCache) 32 if err == nil { 33 return sha, metadataMap, nil 34 } 35 log.Debugf("Metadata cache missed: %v", err) 36 } 37 38 sha, err = shared.GetWPTMetadataMasterSHA(f.ctx, f.gitHubClient) 39 if err != nil { 40 log.Errorf("Error getting HEAD SHA of wpt-metadata: %v", err) 41 42 return nil, nil, err 43 } 44 45 res, err = shared.GetWPTMetadataArchive(f.httpClient, sha) 46 if err != nil { 47 log.Errorf("Error getting archive of wpt-metadata: %v", err) 48 49 return nil, nil, err 50 } 51 52 if err := fillMetadataToRedis(mCache, *sha, res); err != nil { 53 // This is not a fatal failure. 54 log.Errorf("Error storing metadata to cache: %v", err) 55 } 56 57 return sha, res, nil 58 } 59 60 func getMetadataFromRedis(cache shared.ObjectCache) (sha *string, res map[string][]byte, err error) { 61 var metadataSHAMap map[string]map[string][]byte 62 err = cache.Get(metadataCacheKey, &metadataSHAMap) 63 if err != nil { 64 return nil, nil, err 65 } 66 67 // Caches hit; update Metadata. 68 keys := make([]string, 0, len(metadataSHAMap)) 69 for key := range metadataSHAMap { 70 keys = append(keys, key) 71 } 72 73 if len(keys) != 1 { 74 return nil, nil, errors.New("error from getting the wpt-metadata SHA in metadataSHAMap") 75 } 76 77 sha = &keys[0] 78 79 return sha, metadataSHAMap[*sha], nil 80 } 81 82 func fillMetadataToRedis(cache shared.ObjectCache, sha string, metadataByteMap map[string][]byte) error { 83 metadataSHAMap := make(map[string]map[string][]byte) 84 metadataSHAMap[sha] = metadataByteMap 85 86 return cache.Put(metadataCacheKey, metadataSHAMap) 87 }