Skip to content

Commit

Permalink
Implement caching of buildscripts/commits
Browse files Browse the repository at this point in the history
  • Loading branch information
Naatan committed Sep 20, 2024
1 parent 3e54242 commit f056737
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 9 deletions.
34 changes: 28 additions & 6 deletions pkg/platform/model/buildplanner/build.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package buildplanner

import (
"encoding/json"
"errors"
"regexp"
"strconv"
Expand Down Expand Up @@ -53,16 +54,37 @@ func (c *client) Run(req gqlclient.Request, resp interface{}) error {
return c.gqlClient.Run(req, resp)
}

const fetchCommitCacheExpiry = time.Hour * 12

func (b *BuildPlanner) FetchCommit(commitID strfmt.UUID, owner, project string, target *string) (*Commit, error) {
logging.Debug("FetchBuildResult, commitID: %s, owner: %s, project: %s", commitID, owner, project)
logging.Debug("FetchCommit, commitID: %s, owner: %s, project: %s", commitID, owner, project)
resp := &response.ProjectCommitResponse{}
err := b.client.Run(request.ProjectCommit(commitID.String(), owner, project, target), resp)

cacheKey := strings.Join([]string{"FetchCommit", commitID.String(), owner, project, ptr.From(target, "")}, "-")
respRaw, err := b.cache.GetCache(cacheKey)
if err != nil {
err = processBuildPlannerError(err, "failed to fetch commit")
if !b.auth.Authenticated() {
err = errs.AddTips(err, locale.T("tip_private_project_auth"))
return nil, errs.Wrap(err, "failed to get cache")
}
if respRaw != "" {
if err := json.Unmarshal([]byte(respRaw), resp); err != nil {
return nil, errs.Wrap(err, "failed to unmarshal cache: %s", cacheKey)
}
} else {
err := b.client.Run(request.ProjectCommit(commitID.String(), owner, project, target), resp)
if err != nil {
err = processBuildPlannerError(err, "failed to fetch commit")
if !b.auth.Authenticated() {
err = errs.AddTips(err, locale.T("tip_private_project_auth"))
}
return nil, err
}
respBytes, err := json.Marshal(resp)
if err != nil {
return nil, errs.Wrap(err, "failed to marshal cache")
}
if err := b.cache.SetCache(cacheKey, string(respBytes), fetchCommitCacheExpiry); err != nil {
return nil, errs.Wrap(err, "failed to set cache")
}
return nil, err
}

// The BuildPlanner will return a build plan with a status of
Expand Down
24 changes: 24 additions & 0 deletions pkg/platform/model/buildplanner/buildplanner.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package buildplanner

import (
"time"

"github.com/ActiveState/cli/internal/gqlclient"
"github.com/ActiveState/cli/internal/logging"
"github.com/ActiveState/cli/pkg/platform/api"
Expand All @@ -17,6 +19,22 @@ type client struct {
type BuildPlanner struct {
auth *authentication.Auth
client *client
cache cacher
}

type cacher interface {
GetCache(key string) (string, error)
SetCache(key, value string, expiry time.Duration) error
}

type VoidCacher struct{}

func (v VoidCacher) GetCache(key string) (string, error) {
return "", nil
}

func (v VoidCacher) SetCache(key, value string, expiry time.Duration) error {
return nil
}

func NewBuildPlannerModel(auth *authentication.Auth, cache cacher) *BuildPlanner {
Expand All @@ -29,10 +47,16 @@ func NewBuildPlannerModel(auth *authentication.Auth, cache cacher) *BuildPlanner
gqlClient.SetTokenProvider(auth)
}

// To avoid error prone nil checks all over the place
if cache == nil {
cache = VoidCacher{}
}

return &BuildPlanner{
auth: auth,
client: &client{
gqlClient: gqlClient,
},
cache: cache,
}
}
27 changes: 24 additions & 3 deletions pkg/platform/model/buildplanner/buildscript.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package buildplanner

import (
"encoding/json"
"strings"
"time"

"github.com/ActiveState/cli/internal/errs"
Expand All @@ -12,11 +14,30 @@ import (
)

func (b *BuildPlanner) GetBuildScript(commitID string) (*buildscript.BuildScript, error) {
logging.Debug("GetBuildExpression, commitID: %s", commitID)
logging.Debug("GetBuildScript, commitID: %s", commitID)
resp := &bpResp.BuildExpressionResponse{}
err := b.client.Run(request.BuildExpression(commitID), resp)

cacheKey := strings.Join([]string{"GetBuildScript", commitID}, "-")
respRaw, err := b.cache.GetCache(cacheKey)
if err != nil {
return nil, processBuildPlannerError(err, "failed to fetch build expression")
return nil, errs.Wrap(err, "failed to get cache")
}
if respRaw != "" {
if err := json.Unmarshal([]byte(respRaw), resp); err != nil {
return nil, errs.Wrap(err, "failed to unmarshal cache: %s", cacheKey)
}
} else {
err := b.client.Run(request.BuildExpression(commitID), resp)
if err != nil {
return nil, processBuildPlannerError(err, "failed to fetch build expression")
}
respBytes, err := json.Marshal(resp)
if err != nil {
return nil, errs.Wrap(err, "failed to marshal cache")
}
if err := b.cache.SetCache(cacheKey, string(respBytes), fetchCommitCacheExpiry); err != nil {
return nil, errs.Wrap(err, "failed to set cache")
}
}

if resp.Commit == nil {
Expand Down

0 comments on commit f056737

Please sign in to comment.