Skip to content
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

RFC: Caching action #1563

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft

Conversation

ykaliuta
Copy link
Contributor

Abstract caching functionality for actions.

Description

How Has This Been Tested?

Screenshot or short clip

Merge criteria

  • You have read the contributors guide.
  • Commit messages are meaningful - have a clear and concise summary and detailed explanation of what was changed and why.
  • Pull Request contains a description of the solution, a link to the JIRA issue, and to any dependent or related Pull Request.
  • Testing instructions have been added in the PR body (for PRs involving changes that are not immediately obvious).
  • The developer has manually tested the changes and verified that the changes work

ugiordan and others added 6 commits January 23, 2025 17:26
The caching code for all caching Actions is pretty much the same

1) hash the key
2) if the hash is the same as the stored one, return stored resource
3) otherwise render the resource
4) store the key and the resource
5) return the resource

Abastract it with Renderer interface with Render() method which
takes lower level renderer to make a chain. Make Render() return if
it did actual rendering or returned cached value for further
accounting on a higher level.

Signed-off-by: Yauheni Kaliuta <[email protected]>
Create on level on the raw cacher to render Manifests and Templates
which both produce unstructured resources and save them into
ReconcilitaionRequest.

Signed-off-by: Yauheni Kaliuta <[email protected]>
For demo purposes.

Signed-off-by: Yauheni Kaliuta <[email protected]>
Copy link

openshift-ci bot commented Jan 24, 2025

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

Copy link

openshift-ci bot commented Jan 24, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from ykaliuta. For more information see the Code Review Process.

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

@ykaliuta
Copy link
Contributor Author

/cc @lburgazzoli

@openshift-ci openshift-ci bot requested a review from lburgazzoli January 24, 2025 15:58
Copy link
Contributor

This PR can't be merged just yet 😢

Please run make generate manifests api-docs and commit the changes.

For more info: https://github.com/opendatahub-io/opendatahub-operator/actions/runs/12953054333

Copy link

codecov bot commented Jan 24, 2025

Codecov Report

Attention: Patch coverage is 31.72414% with 99 lines in your changes missing coverage. Please review.

Project coverage is 19.79%. Comparing base (912dcaa) to head (f316a77).
Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
...ns/status/releases/action_fetch_releases_status.go 0.00% 66 Missing ⚠️
...ontroller/actions/resourcecacher/resourcecacher.go 63.33% 8 Missing and 3 partials ⚠️
pkg/controller/actions/cacher/cacher.go 69.23% 6 Missing and 2 partials ⚠️
...ctions/render/kustomize/action_render_manifests.go 69.23% 3 Missing and 1 partial ⚠️
...llers/components/codeflare/codeflare_controller.go 0.00% 3 Missing ⚠️
...llers/components/dashboard/dashboard_controller.go 0.00% 1 Missing ⚠️
...ciencepipelines/datasciencepipelines_controller.go 0.00% 1 Missing ⚠️
controllers/components/kueue/kueue_controller.go 0.00% 1 Missing ⚠️
...mponents/modelregistry/modelregistry_controller.go 0.00% 1 Missing ⚠️
controllers/components/ray/ray_controller.go 0.00% 1 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1563      +/-   ##
==========================================
- Coverage   19.84%   19.79%   -0.05%     
==========================================
  Files         159      162       +3     
  Lines       10794    10899     +105     
==========================================
+ Hits         2142     2158      +16     
- Misses       8424     8511      +87     
- Partials      228      230       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

"github.com/opendatahub-io/opendatahub-operator/v2/pkg/controller/types"
)

type Renderer interface {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
type Renderer interface {
// Renderer defines an interface for rendering resources.
type Renderer interface {

Render(r Renderer, rr *types.ReconciliationRequest) (any, bool, error)
}

type CachingKeyFn func(rr *types.ReconciliationRequest) ([]byte, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
type CachingKeyFn func(rr *types.ReconciliationRequest) ([]byte, error)
// CachingKeyFn is a function type used to generate a caching key based on the reconciliation request.
type CachingKeyFn func(rr *types.ReconciliationRequest) ([]byte, error)


type CachingKeyFn func(rr *types.ReconciliationRequest) ([]byte, error)

type Cacher struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
type Cacher struct {
// Cacher provides caching capabilities for rendered resources.
type Cacher struct {

s.cachingKeyFn = key
}

func (s *Cacher) InvalidateCache() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (s *Cacher) InvalidateCache() {
// InvalidateCache clears the cached key and resources, forcing a re-render on the next invocation.
func (s *Cacher) InvalidateCache() {


type CacherOpts func(*Cacher)

func (s *Cacher) SetKey(key CachingKeyFn) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (s *Cacher) SetKey(key CachingKeyFn) {
// SetKey sets the caching key function for the Cacher.
func (s *Cacher) SetKey(key CachingKeyFn) {

resList := resources.UnstructuredList(resUnstructured)

if acted {
controllerName := strings.ToLower(rr.Instance.GetObjectKind().GroupVersionKind().Kind)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
controllerName := strings.ToLower(rr.Instance.GetObjectKind().GroupVersionKind().Kind)
// Track the number of rendered resources for monitoring
controllerName := strings.ToLower(rr.Instance.GetObjectKind().GroupVersionKind().Kind)

controllerName := strings.ToLower(rr.Instance.GetObjectKind().GroupVersionKind().Kind)
render.RenderedResourcesTotal.WithLabelValues(controllerName, s.Name()).Add(float64(len(resList)))

rr.Generated = true
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
rr.Generated = true
// Mark the reconciliation request as having generated resources
rr.Generated = true

Comment on lines +54 to +55
// deep copy object so changes done in the pipelines won't
// alter them
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// deep copy object so changes done in the pipelines won't
// alter them
// Append cloned resources to the reconciliation request,
// ensuring a deep copy so changes in the pipeline don't alter the original objects.

rr.Resources = append(rr.Resources, result.Clone()...)

return nil
return res, true, nil
}

func (a *Action) render(rr *types.ReconciliationRequest) ([]unstructured.Unstructured, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (a *Action) render(rr *types.ReconciliationRequest) ([]unstructured.Unstructured, error) {
// render handles the rendering of resources using the Kustomize engine.
func (a *Action) render(rr *types.ReconciliationRequest) ([]unstructured.Unstructured, error) {


rr.Generated = true
func (a *Action) Render(_ cacher.Renderer, rr *types.ReconciliationRequest) (any, bool, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (a *Action) Render(_ cacher.Renderer, rr *types.ReconciliationRequest) (any, bool, error) {
// Render is a wrapper for rendering the reconciliation request using Kustomize.
// It returns the rendered resources and indicates if any resources were acted upon.
func (a *Action) Render(_ cacher.Renderer, rr *types.ReconciliationRequest) (any, bool, error) {

@ugiordan
Copy link
Contributor

ugiordan commented Jan 27, 2025

@ykaliuta, I believe the same caching abstraction can be applied to the action_render_templates as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

Successfully merging this pull request may close these issues.

2 participants