Skip to content

Add shared cache for resolvers #8825

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

brianwcook
Copy link

@brianwcook brianwcook commented Jun 12, 2025

Changes

Resolvers are awesome but can be noisy. In high traffic environments we have seen rate limiting both from registries when using the bundle resolver and from git forges when using the git resolver. This PR adds caching to the resolvers (except the cluster resolver). It is only enabled by default when 'safe' - meaning that the object was fetched by some hash / digest. Otherwise, it can be turned on with a resolver parameter.

Note

This PR is a work in progress posted for initial thoughts and feedback. It works for some cases already (git resolver) - others, maybe not.

Submitter Checklist

As the author of this PR, please check off the items in this checklist:

  • Has Docs if any changes are user facing, including updates to minimum requirements e.g. Kubernetes version bumps
  • Has Tests included if any functionality added or changed
  • pre-commit Passed
  • Follows the commit message standard
  • Meets the Tekton contributor standards (including functionality, content, code)
  • Has a kind label. You can add one by adding a comment on this PR that contains /kind <type>. Valid types are bug, cleanup, design, documentation, feature, flake, misc, question, tep
  • Release notes block below has been updated with any user facing changes (API changes, bug fixes, changes requiring upgrade notices or deprecation warnings). See some examples of good release notes.
  • Release notes contains the string "action required" if the change requires additional action from users switching to the new release

Release Notes

Remote resolver results for bundle and git resolvers which use immutable references will be cached by default for 5 minutes. User can opt-in to caching non-immutable references or disable caching entirely. The default caching mode (auto) should be safe and entirely transparent for existing users.

@tekton-robot tekton-robot added release-note-none Denotes a PR that doesnt merit a release note. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. labels Jun 12, 2025
Copy link

linux-foundation-easycla bot commented Jun 12, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: brianwcook / name: Brian Cook (0d1fc0e)

@tekton-robot tekton-robot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Jun 12, 2025
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 86.4%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 62.1% -19.7
pkg/remoteresolution/resolver/http/resolver.go 88.9% 78.1% -10.8
pkg/remoteresolution/resolver/hub/resolver.go 50.0% 57.1% 7.1
pkg/resolution/resolver/framework/cache.go Do not exist 29.4%

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 86.4%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 62.1% -19.7
pkg/remoteresolution/resolver/http/resolver.go 88.9% 78.1% -10.8
pkg/remoteresolution/resolver/hub/resolver.go 50.0% 57.1% 7.1
pkg/resolution/resolver/bundle/params.go 87.9% 88.2% 0.4

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 86.4%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 82.9% 1.1
pkg/remoteresolution/resolver/http/resolver.go 88.9% 78.1% -10.8
pkg/remoteresolution/resolver/hub/resolver.go 50.0% 57.1% 7.1
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8

@tekton-robot tekton-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Jun 13, 2025
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 86.4%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 82.9% 1.1
pkg/remoteresolution/resolver/git/resolver.go 82.4% 65.0% -17.4
pkg/remoteresolution/resolver/http/resolver.go 88.9% 78.1% -10.8
pkg/remoteresolution/resolver/hub/resolver.go 50.0% 57.1% 7.1
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8

@tekton-robot tekton-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Jun 13, 2025
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 58.3%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 83.7% 1.9
pkg/remoteresolution/resolver/git/resolver.go 82.4% 83.9% 1.5
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8
pkg/resolution/resolver/git/resolver.go 84.9% 84.3% -0.6

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 58.3%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 83.7% 1.9
pkg/remoteresolution/resolver/git/resolver.go 82.4% 83.9% 1.5
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8
pkg/resolution/resolver/git/resolver.go 84.9% 84.3% -0.6

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 58.3%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 83.7% 1.9
pkg/remoteresolution/resolver/git/resolver.go 82.4% 83.9% 1.5
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8
pkg/resolution/resolver/git/resolver.go 84.9% 84.3% -0.6

@brianwcook
Copy link
Author

/kind feature

@tekton-robot tekton-robot added the kind/feature Categorizes issue or PR as related to a new feature. label Jun 14, 2025
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 58.3%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 83.7% 1.9
pkg/remoteresolution/resolver/git/resolver.go 82.4% 83.9% 1.5
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8
pkg/resolution/resolver/git/resolver.go 84.9% 84.3% -0.6

@tekton-robot tekton-robot removed the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Jun 15, 2025
@vdemeester vdemeester self-assigned this Jun 16, 2025
@tekton-robot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please ask for approval from vdemeester after the PR has been reviewed.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 85.0%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 83.7% 1.9
pkg/remoteresolution/resolver/git/resolver.go 82.4% 83.9% 1.5
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8
pkg/resolution/resolver/git/resolver.go 84.9% 84.3% -0.6

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 85.0%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 83.7% 1.9
pkg/remoteresolution/resolver/git/resolver.go 82.4% 83.9% 1.5
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8
pkg/resolution/resolver/git/resolver.go 84.9% 84.3% -0.6

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 85.0%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 83.7% 1.9
pkg/remoteresolution/resolver/git/resolver.go 82.4% 83.9% 1.5
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8
pkg/resolution/resolver/git/resolver.go 84.9% 84.3% -0.6

@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 85.0%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 83.7% 1.9
pkg/remoteresolution/resolver/git/resolver.go 82.4% 83.9% 1.5
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8
pkg/resolution/resolver/git/resolver.go 84.9% 84.3% -0.6

@vdemeester vdemeester added this to the v1.3.0 (LTS) milestone Jul 15, 2025
@twoGiants
Copy link
Member

/assign

@brianwcook brianwcook marked this pull request as ready for review July 16, 2025 12:44
@tekton-robot tekton-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 16, 2025
@tekton-robot tekton-robot requested review from abayer and dibyom July 16, 2025 12:44
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 85.0%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 83.7% 1.9
pkg/remoteresolution/resolver/git/resolver.go 82.4% 83.9% 1.5
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8
pkg/resolution/resolver/git/resolver.go 84.9% 84.3% -0.6

@brianwcook
Copy link
Author

/test all

@tekton-robot
Copy link
Collaborator

@brianwcook: No presubmit jobs available for tektoncd/pipeline@main

In response to this:

/test all

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

This commit adds caching for bundle and git resolvers to reduce
chances of being rate limited by registries and git forges.

- Add cache interface and in-memory implementation
- Add cache configuration options for bundle and git resolvers
- Add documentation for cache configuration

Signed-off-by: Brian Cook <bcook@redhat.com>
@tekton-robot
Copy link
Collaborator

The following is the coverage report on the affected files.
Say /test pull-tekton-pipeline-go-coverage-df to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/remoteresolution/cache/cache.go Do not exist 85.0%
pkg/remoteresolution/resolver/bundle/resolver.go 81.8% 83.7% 1.9
pkg/remoteresolution/resolver/git/resolver.go 82.4% 83.9% 1.5
pkg/resolution/resolver/bundle/bundle.go 71.1% 71.4% 0.4
pkg/resolution/resolver/bundle/params.go 87.9% 86.1% -1.8
pkg/resolution/resolver/git/resolver.go 84.9% 84.3% -0.6

@brianwcook
Copy link
Author

i see in the failed test:

arendelle-bqh7s 28m Warning Failed pod/task-run-steps-termination-reasons-termin-oequuhxg-pod Failed to pull image "busybox@sha256:895ab622e92e18d6b461d671081757af7dbaa3b00e3e28e12505af7817f73649": failed to pull and unpack image "docker.io/library/busybox@sha256:895ab622e92e18d6b461d671081757af7dbaa3b00e3e28e12505af7817f73649": failed to copy: httpReadSeeker: failed open: unexpected status code https://registry-1.docker.io/v2/library/busybox/manifests/sha256:895ab622e92e18d6b461d671081757af7dbaa3b00e3e28e12505af7817f73649: 429 Too Many Requests - Server message: toomanyrequests: You have reached your unauthenticated pull rate limit.

@vdemeester
Copy link
Member

/retest

Copy link
Member

@twoGiants twoGiants left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @brianwcook ! Thank you for this great contribution 😸 👍

The PR status is open and I started reviewing but it looks like its still work in progress if I am not mistaken. I thought to publish the comments I have so far anyway, I hope it's ok and hope they are helpful.

I think this PR would benefit from a few e2e tests.

Another consideration is to maybe extend caching to the cluster resolver. I had a conversation with a user on Slack last week and he might be running into rate limiting imposed by k8 when fetching many (100+) tasks. Here is the issue #8889, but it has not all the details. The thread in slack has more details.

}
}

// Resolve uses the given params to resolve the requested file or resource.
func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) {
if len(req.Params) > 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use the guard pattern here. It makes the code better readable:

Suggested change
if len(req.Params) > 0 {
if len(req.Params) == 0 {
// Remove this error once resolution of url has been implemented.
return nil, errors.New("the Resolve method has not been implemented.")
}
if bundle.IsDisabled(ctx) {
return nil, errors.New(bundle.DisabledError)
}
// ... all the other code

cache.GetGlobalCache().InitializeLogger(ctx)

// Generate cache key
cacheKey, err := cache.GenerateCacheKey(LabelValueBundleResolverType, req.Params)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generating cacheKey and getting a value from cache could be one Get operation taking LabelValueBundleResolverType, req.Params as arguments. It would simplify the code here a bit.


if useCache {
// Initialize cache logger
cache.GetGlobalCache().InitializeLogger(ctx)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add cache as a property to the Resolver struct and initialize the cache logger in the main right before passing it to framework.NewController(ctx, &bundle.Resolver{cache: cache.GetGlobalCache()}) from cmd/resolvers/main.go.

// Determine if caching should be used based on cache mode
useCache := ShouldUseCache(opts)

if useCache {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ShouldUseCache(opts) can be used here and in the other if statement, the name is descriptive and there would be one local variable less.


// Cache the result if caching is enabled
if useCache {
cacheKey, _ := cache.GenerateCacheKey(LabelValueBundleResolverType, req.Params)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar here. Both operations could be just the Add operation handling cacheKey generation internally.

}
}

// Resolve uses the given params to resolve the requested file or resource.
func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a bit of new logic now added to the Resolve method so it makes sense to write a few unit tests for it. Easier said then done when I take a look at TestResolve in pkg/remoteresolution/resolver/bundle/resolver_test.go.

But I think with a small refactoring here you could easy write unit tests just for this method without the need for a complex test setup.

Put bundle.ResolveRequest as a function property on Resolver and set it in main.go then you can easy fake it in your unit tests.

return IsCommitHash(gitRevision)
}
}

// Resolve performs the work of fetching a file from git given a map of
// parameters.
func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) {
Copy link
Member

@twoGiants twoGiants Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most comments from the bundle resolver apply here also:

  • using guard pattern
  • setting cache as a property on the Resolver struct (and rename the current cache to secretCache)
  • inline useCache variable
  • simplify cache usage by keeping cacheKey generation inside Get and Add
  • use function properties for testing
  • adding unit tests to it

}

// Check cache first
if cached, ok := cache.GetGlobalCache().Get(cacheKey); ok {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use generics here but if its only resolutionframework.ResolvedResource which is returned the cache could also be specific and return only this resource.

if params[git.UrlParam] != "" {
return g.ResolveGitClone(ctx)
resource, err = g.ResolveGitClone(ctx)
Copy link
Member

@twoGiants twoGiants Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you put ResolveGitClone and ResolveAPIGit as function properties on this struct instead on GitResolver down below you could overwrite them here for testing and testing of this method becomes easier.


// Check cache first
if cached, ok := cache.GetGlobalCache().Get(cacheKey); ok {
if resource, ok := cached.(resolutionframework.ResolvedResource); ok {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just food for thought: does it makes sense to find a way to enrich ResolvedResource somehow with an annotation that it was cached? This would make unit/e2e tests easier. Wdys?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
Status: Todo
Development

Successfully merging this pull request may close these issues.

4 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy