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

kclient: use internal indexes instead of external #51576

Merged
merged 2 commits into from
Jun 24, 2024

Conversation

howardjohn
Copy link
Member

Before: we register an informer handler which builds our own index on
top of the underlying store.

After: we register an index directly into the informer, which handles
things entirely.

This was not done originally because Kubernetes only added the ability
to add indexes dynamically recently (I added this).

The benefits here are:

  • Deterministic ordering. The index is ALWAYS updated before any other
    handlers are called. This allows us to guarantee the index is up to
    date in our handlers. Without this, we had the crazy Delegate hack.
  • Minor performance benefit from not needing to cut through as many
    abstractions or locking.

K8s indexes are actually a pain to use, so kclient provides a higher
level API over it; the same as what we had before. One quirk is they
only allow string keys. To get around this, we allow any key, but it
must compile down to a unique string.

Before: we register an informer handler which builds our own index on
top of the underlying store.

After: we register an index directly into the informer, which handles
things entirely.

This was not done originally because Kubernetes only added the ability
to add indexes dynamically recently (I added this).

The benefits here are:
* Deterministic ordering. The index is ALWAYS updated before any other
  handlers are called. This allows us to guarantee the index is up to
date in our handlers. Without this, we had the crazy Delegate hack.
* Minor performance benefit from not needing to cut through as many
  abstractions or locking.

K8s indexes are actually a pain to use, so kclient provides a higher
level API over it; the same as what we had before. One quirk is they
only allow string keys. To get around this, we allow any key, but it
must compile down to a unique string.
@howardjohn howardjohn requested a review from a team as a code owner June 13, 2024 20:44
@howardjohn howardjohn added the release-notes-none Indicates a PR that does not require release notes. label Jun 13, 2024
@howardjohn howardjohn requested review from a team as code owners June 13, 2024 20:44
@istio-testing istio-testing added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jun 13, 2024
pkg/kube/kclient/client_test.go Show resolved Hide resolved
@stevenctl stevenctl added the do-not-merge/hold Block automatic merging of a PR. label Jun 18, 2024
@howardjohn howardjohn removed the do-not-merge/hold Block automatic merging of a PR. label Jun 18, 2024
@howardjohn howardjohn assigned jaellio and unassigned keithmattix Jun 18, 2024
@hzxuzhonghu
Copy link
Member

hzxuzhonghu commented Jun 19, 2024

I am very concerned about frequently changing the funamental framework we are using. Transiting from k8s client to kclient, there are many bugs met.

This is also the most important reason that i am opposed to migrate all of our components to krt.

res, err := i.indexer.ByIndex(i.key, key)
if err != nil {
// This should only happen if the key does not exist which should be impossible
log.Fatalf("index lookup failed: %v", err)
Copy link
Member

Choose a reason for hiding this comment

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

why i.indexer.ByIndex cannot return not exist error, where do you protect it

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 only time it returns an error is if the index doesn't exist. We know not must exist because we were the ones that created it

@howardjohn
Copy link
Member Author

I am very concerned about frequently changing the funamental framework we are using. Transiting from k8s client to kclient, there are many bugs met.

This is also the most important reason that i am opposed to migrate all of our components to krt.

I am not sure what to do with this feedback. This particular PR was always the intended path forward (and had Todos in the code, etc) but was blocked by client-go limitations which I fixed upstream. Overall kclient has, IMO been a huge improvement in development and fixed a ton of bugs. While it has introduced a few minor bugs, it has overall been a net positive imo.

I am not suggesting we move everything to krt, and tbh I wasn't even the reason it was - there was an overwhelming majority of contributors who wanted to see it used for ambient and we haven't agreed yet to use it more broadly.

Overall I feel I made a change that somplifies our code, improves performance, and fixes bugs. It's hard to react to a comment that we shouldn't make such a change without more concrete feedback for how to improve it or what the issue is

@howardjohn howardjohn requested a review from jaellio June 24, 2024 19:02
func (i internalIndex) Lookup(key string) []interface{} {
res, err := i.indexer.ByIndex(i.key, key)
if err != nil {
// This should only happen if the key does not exist which should be impossible
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you clarify which key you are referring to? The key for the internal index or the passed key

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 internal index. Ill update the comment

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@istio-testing istio-testing merged commit ca141c8 into istio:master Jun 24, 2024
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release-notes-none Indicates a PR that does not require release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants