Skip to content

Commit

Permalink
Ensure we use the correct atTime when ingredient was cached at a newe…
Browse files Browse the repository at this point in the history
…r timestamp
  • Loading branch information
Naatan committed Nov 8, 2024
1 parent c1fc008 commit c20a2fb
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
52 changes: 46 additions & 6 deletions internal/runners/commit/ingredientcall.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ func (i *IngredientCall) Resolve() error {
return errs.Wrap(err, "Could not hash ingredient call")
}

resolvedIngredient, err := i.getCached(hash)
latest, err := model.FetchLatestRevisionTimeStamp(nil)
if err != nil {
return errs.Wrap(err, "Unable to determine latest revision time")
}
resolvedIngredient, err := i.getCached(hash, latest)
if err != nil {
return errs.Wrap(err, "Could not check if ingredient call is cached")
}
Expand All @@ -80,11 +84,11 @@ func (i *IngredientCall) Resolve() error {
return errs.Wrap(err, "Could not create ingredient")
}
// Bump timestamp, because otherwise the new ingredient will be unusable
latest, err := model.FetchLatestRevisionTimeStamp(nil)
if err != nil {
return errs.Wrap(err, "Unable to determine latest revision time")
}
i.script.SetAtTime(latest, true)
} else {
// Update atTime according to ingredient. This MAY not actually be an update if the resolvedIngredient has
// the same atTime as the stored buildscript.
i.script.SetAtTime(resolvedIngredient.AtTime, true)
}

// Add/update arguments on the buildscript ingredient function call
Expand Down Expand Up @@ -138,9 +142,15 @@ func (i *IngredientCall) createIngredient(hash string, hashedFiles []*graph.Glob
return nil, errs.Wrap(err, "Could not create publish request")
}

latest, err := model.FetchLatestRevisionTimeStamp(nil)
if err != nil {
return nil, errs.Wrap(err, "Unable to determine latest revision time")
}

return &resolvedIngredientData{
VersionID: pr.IngredientVersionID,
Revision: pr.Revision,
AtTime: latest,
}, nil
}

Expand Down Expand Up @@ -290,11 +300,24 @@ func parseFeature(f string) (request.PublishVariableFeature, error) {
type resolvedIngredientData struct {
VersionID string
Revision int
AtTime time.Time
}

// MarshalJSON works around go's json.Marshal not allowing you to specify the format of time fields
func (r resolvedIngredientData) MarshalJSON() ([]byte, error) {
type Alias resolvedIngredientData
return json.Marshal(&struct {
Alias
AtTime string
}{
Alias: Alias(r),
AtTime: r.AtTime.Format(time.RFC3339),
})
}

// getCached checks against our local cache to see if we've already handled this file hash, and if no local cache
// exists checks against the platform ingredient API.
func (i *IngredientCall) getCached(hash string) (*resolvedIngredientData, error) {
func (i *IngredientCall) getCached(hash string, latest time.Time) (*resolvedIngredientData, error) {
cacheValue, err := i.prime.SvcModel().GetCache(fmt.Sprintf(cacheKeyFiles, hash))
if err != nil {
return nil, errs.Wrap(err, "Could not get build script cache")
Expand All @@ -319,6 +342,23 @@ func (i *IngredientCall) getCached(hash string) (*resolvedIngredientData, error)
return &resolvedIngredientData{
VersionID: string(*ingredients[0].LatestVersion.IngredientVersionID),
Revision: int(*ingredients[0].LatestVersion.Revision),
AtTime: ptr.From(i.script.AtTime(), latest), // Fall back to latest if script has no AtTime
}, nil
}

// Check again if the hash exists at the latest timestamp, because even if the ingredient exists, it might not exist
// at the atTime of the buildscript. In which case the buildscript will need to bump its timestamp without touching
// the ingredient.
ingredients, err = model.SearchIngredientsStrict(i.ns.String(), hash, true, false, &latest, i.prime.Auth())
if err != nil && !errors.As(err, ptr.To(&model.ErrSearch404{})) {
return nil, errs.Wrap(err, "Could not search ingredients")
}
if len(ingredients) > 0 {
// Ingredient already exists
return &resolvedIngredientData{
VersionID: string(*ingredients[0].LatestVersion.IngredientVersionID),
Revision: int(*ingredients[0].LatestVersion.Revision),
AtTime: latest,
}, nil
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/platform/model/buildplanner/buildscript.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (b *BuildPlanner) GetBuildScript(commitID string) (*buildscript.BuildScript
}

script := buildscript.New()
script.SetAtTime(time.Time(resp.Commit.AtTime), false)
script.SetAtTime(time.Time(resp.Commit.AtTime), true)
if err := script.UnmarshalBuildExpression(resp.Commit.Expression); err != nil {
return nil, errs.Wrap(err, "failed to parse build expression")
}
Expand Down

0 comments on commit c20a2fb

Please sign in to comment.