Skip to content

Commit

Permalink
Improve Granted startup time when HTTP registry is used (#673)
Browse files Browse the repository at this point in the history
defers calling `config.LoadDefault()` every time `assume` is called, which makes startup instant rather than taking ~1s to obtain an access token.
  • Loading branch information
chrnorm authored Jun 3, 2024
1 parent 84efb8b commit 9b245f6
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 17 deletions.
2 changes: 1 addition & 1 deletion pkg/granted/registry/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ var AddCommand = cli.Command{
return nil
} else {

registry, err := cfregistry.New(cfregistry.Opts{
registry := cfregistry.New(cfregistry.Opts{
Name: name,
URL: URL,
})
Expand Down
47 changes: 36 additions & 11 deletions pkg/granted/registry/cfregistry/cfregistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cfregistry

import (
"context"
"sync"

"connectrpc.com/connect"
"github.com/common-fate/sdk/config"
Expand All @@ -12,41 +13,65 @@ import (
)

type Registry struct {
opts Opts
Client awsv1alpha1connect.ProfileRegistryServiceClient
opts Opts
mu sync.Mutex
// client is the profile registry service client.
//
// Do not use client directly. Instead, call
// r.getClient() which will automatically populate it.
client awsv1alpha1connect.ProfileRegistryServiceClient
}

type Opts struct {
Name string
URL string
}

func New(opts Opts) (*Registry, error) {

// getClient lazily loads the Profile Registry service client.
//
// Becuase the Registry is constructed every time the Granted CLI executes,
// calling `config.LoadDefault()` when creating the registry makes Granted very slow.
// Instead, we only obtain an OIDC token if we actually need to load profiles for the registry.
func (r *Registry) getClient() (awsv1alpha1connect.ProfileRegistryServiceClient, error) {
// if the cached
if r.client != nil {
return r.client, nil
}
cfg, err := config.LoadDefault(context.Background())
if err != nil {
return nil, err
}

accountClient := grantedv1alpha1.NewFromConfig(cfg)

p := Registry{
opts: opts,
Client: accountClient,
r.mu.Lock()
defer r.mu.Unlock()
r.client = accountClient

return r.client, nil
}

func New(opts Opts) *Registry {
r := Registry{
opts: opts,
}

return &p, nil
return &r
}

func (r Registry) AWSProfiles(ctx context.Context) (*ini.File, error) {
// call common fate api to pull profiles
func (r *Registry) AWSProfiles(ctx context.Context) (*ini.File, error) {
client, err := r.getClient()
if err != nil {
return nil, err
}

// call the Profile Registry API to pull the avilable profiles.
done := false
var pageToken string
profiles := []*awsv1alpha1.Profile{}

for !done {
listProfiles, err := r.Client.ListProfiles(ctx, &connect.Request[awsv1alpha1.ListProfilesRequest]{
listProfiles, err := client.ListProfiles(ctx, &connect.Request[awsv1alpha1.ListProfilesRequest]{
Msg: &awsv1alpha1.ListProfilesRequest{
PageToken: pageToken,
},
Expand Down
6 changes: 1 addition & 5 deletions pkg/granted/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,10 @@ func GetProfileRegistries(interactive bool) ([]loadedRegistry, error) {
})
} else {
//set up a common fate registry
reg, err := cfregistry.New(cfregistry.Opts{
reg := cfregistry.New(cfregistry.Opts{
Name: r.Name,
URL: r.URL,
})

if err != nil {
return nil, err
}
registries = append(registries, loadedRegistry{
Config: r,
Registry: reg,
Expand Down

0 comments on commit 9b245f6

Please sign in to comment.