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

fix(HMS-1800): refactor and add more caching #534

Merged
merged 1 commit into from
May 17, 2023

Conversation

lzap
Copy link
Member

@lzap lzap commented May 16, 2023

This is complete refactoring of the caching package. Initially, there was a memory implementation, then Redis was added and also noop for tests - many interfaces and it was a bit over-engineered to my taste. Everything is now simplified: cache can be enabled (Redis) or disabled (no caching, the default). The API is vastly more simple with only few functions available and it makes use of Go generics as well as Gob binary encoding for seamless experience. It is now a type-safe cache that is easy to work with and adding a new model/type is just three lines change.

It started as adding support for upload info caching but the more I digged into the old design the more I wanted to refactor this from scratch. As part of one commit, this also adds caching for:

  • Account Details for AWS (whole model)
  • Azure Tenant ID (only the ID which is then used for upload info endpoint)

Finally, metrics were improved - alongside with hits and misses also errors are reported. I am going to create a new graph on the dashboard so we can take a look on cache success rate or error ratio. Maybe as part of this PR if I have chance.

Added also integration tests for Redis. No upgrade is needed, everytime a cache encounters a deserialization error, it is reported into logs and prometheus, but ErrNotFound is returned so the caller will effectively overwrite the old entry with new data.

@lzap lzap changed the title Cache hsacc fix(HMS-1800): refactor and add more caching May 16, 2023
AzureInfo *clients.AzureSourceDetail `json:"azure" nullable:"true"`
Provider string `json:"provider"`
AwsInfo *clients.AccountDetailsAWS `json:"aws" nullable:"true"`
AzureInfo *clients.AccountDetailsAzure `json:"azure" nullable:"true"`
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Because the new cache key is based on generics and type infers the prefix, string build-in type cannot be used. So I introduced a special type here.


type Cacheable interface {
models.Account | clients.AccountDetailsAWS | clients.AzureTenantId
}
Copy link
Member Author

Choose a reason for hiding this comment

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

To add a new generic type to cache, change here.

default:
return "", ErrUnknownType
}
}
Copy link
Member Author

Choose a reason for hiding this comment

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

To add a new generic type to cache, change here.

// nolint: wrapcheck
func Set[T Cacheable](ctx context.Context, key string, value *T) error {
return SetExpires(ctx, key, value, config.Application.Cache.Expiration)
}
Copy link
Member Author

Choose a reason for hiding this comment

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

The interface is simple:

  • Find
  • Set
  • SetForever (with a very long expiration)
  • SetExpires (with your own expiration duration)

I see I forgot to document these functions, will do during rebase.

Copy link
Member

@ezr-ondrej ezr-ondrej left a comment

Choose a reason for hiding this comment

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

The code looks sane to me! 👍

return nil
}

func Prefix[T Cacheable](value *T) (string, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Looks weird to use generics and then still switch by type.
Why is it better then having SetXXX functions? 🤔

EDIT: or interface Cacheable with CacheKey method?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I rebased the code to use interface normally instead of constraint. This is indeed more natural and better, good point.

@lzap lzap force-pushed the cache-hsacc branch 9 times, most recently from d7d03ba to 28e10db Compare May 17, 2023 12:06
@lzap
Copy link
Member Author

lzap commented May 17, 2023

Linter error solution: #537

Signed-off-by: Lukáš Zapletal <lzap+git@redhat.com>
Copy link
Member

@ezr-ondrej ezr-ondrej left a comment

Choose a reason for hiding this comment

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

Loving it 🧡

@ezr-ondrej ezr-ondrej merged commit decfb33 into RHEnVision:main May 17, 2023
7 checks passed
@lzap lzap deleted the cache-hsacc branch May 19, 2023 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants