github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/cache/projectcache/projectid.go (about) 1 package projectcache 2 3 import ( 4 "sync" 5 "time" 6 7 "github.com/ActiveState/cli/internal/errs" 8 "github.com/ActiveState/cli/pkg/platform/authentication" 9 "github.com/ActiveState/cli/pkg/platform/model" 10 "github.com/ActiveState/cli/pkg/project" 11 "github.com/patrickmn/go-cache" 12 ) 13 14 type ID struct { 15 projectIDCache *cache.Cache 16 projectIDMutex *sync.Mutex // used to synchronize API calls resolving the projectID 17 } 18 19 func NewID() *ID { 20 return &ID{ 21 cache.New(30*time.Minute, time.Hour), 22 &sync.Mutex{}, 23 } 24 } 25 26 // FromNamespace resolves the projectID from projectName and caches the result 27 func (i *ID) FromNamespace(projectNameSpace string, auth *authentication.Auth) (string, error) { 28 // Lock mutex to prevent resolving the same projectName more than once 29 i.projectIDMutex.Lock() 30 defer i.projectIDMutex.Unlock() 31 32 if pi, ok := i.projectIDCache.Get(projectNameSpace); ok { 33 return pi.(string), nil 34 } 35 36 pn, err := project.ParseNamespace(projectNameSpace) 37 if err != nil { 38 return "", errs.Wrap(err, "Failed to parse project namespace %s", projectNameSpace) 39 } 40 41 if err := auth.Refresh(); err != nil { 42 return "", errs.Wrap(err, "Failed to refresh authentication") 43 } 44 pj, err := model.LegacyFetchProjectByName(pn.Owner, pn.Project) 45 if err != nil { 46 return "", errs.Wrap(err, "Failed get project by name") 47 } 48 49 pi := string(pj.ProjectID) 50 i.projectIDCache.Set(projectNameSpace, pi, cache.DefaultExpiration) 51 52 return string(pj.ProjectID), nil 53 }