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  }