Cache workspaces based on full path. (#1326)
As it stands, we recompute the workspace for the current directory potentially many times during some CLI operations, most notably `stack ls`. These changes add a simple cache based on the complete path passed to `NewFrom`, and eliminate some lagginess in `stack ls` when there are multiple stacks. Another option is to calculate the current workspace once in the CLI and then fetch it as necessary.
This commit is contained in:
parent
d1b49d25f8
commit
a5e92b9497
|
@ -11,6 +11,7 @@ import (
|
|||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/pulumi/pulumi/pkg/resource/config"
|
||||
|
@ -32,6 +33,26 @@ type projectWorkspace struct {
|
|||
repo *Repository // the repo this workspace is associated with.
|
||||
}
|
||||
|
||||
var cache = make(map[string]W)
|
||||
var cacheMutex sync.RWMutex
|
||||
|
||||
func loadFromCache(key string) (W, bool) {
|
||||
cacheMutex.RLock()
|
||||
defer cacheMutex.RUnlock()
|
||||
|
||||
w, ok := cache[key]
|
||||
return w, ok
|
||||
}
|
||||
|
||||
func upsertIntoCache(key string, w W) {
|
||||
contract.Require(w != nil, "w")
|
||||
|
||||
cacheMutex.Lock()
|
||||
defer cacheMutex.Unlock()
|
||||
|
||||
cache[key] = w
|
||||
}
|
||||
|
||||
// New creates a new workspace using the current working directory.
|
||||
func New() (W, error) {
|
||||
cwd, err := os.Getwd()
|
||||
|
@ -44,6 +65,16 @@ func New() (W, error) {
|
|||
// NewFrom creates a new Pulumi workspace in the given directory. Requires a Pulumi.yaml file be present in the
|
||||
// folder hierarchy between dir and the .pulumi folder.
|
||||
func NewFrom(dir string) (W, error) {
|
||||
absDir, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dir = absDir
|
||||
|
||||
if w, ok := loadFromCache(dir); ok {
|
||||
return w, nil
|
||||
}
|
||||
|
||||
repo, err := GetRepository(dir)
|
||||
if err == ErrNoRepository {
|
||||
repo = nil
|
||||
|
@ -63,7 +94,7 @@ func NewFrom(dir string) (W, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
w := projectWorkspace{
|
||||
w := &projectWorkspace{
|
||||
name: proj.Name,
|
||||
project: path,
|
||||
repo: repo,
|
||||
|
@ -78,7 +109,8 @@ func NewFrom(dir string) (W, error) {
|
|||
w.settings.ConfigDeprecated = make(map[tokens.QName]config.Map)
|
||||
}
|
||||
|
||||
return &w, nil
|
||||
upsertIntoCache(dir, w)
|
||||
return w, nil
|
||||
}
|
||||
|
||||
func (pw *projectWorkspace) Settings() *Settings {
|
||||
|
|
Loading…
Reference in a new issue