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

Make extension components ready for cached client #4027

Merged
merged 16 commits into from
Jun 1, 2021

Conversation

timebertt
Copy link
Member

@timebertt timebertt commented May 11, 2021

How to categorize this PR?

/area dev-productivity scalability
/kind cleanup

What this PR does / why we need it:

Similar to previous PRs, this PR works towards getting rid of the DirectClient.
This one tackles usages in the extension components and makes them ready for cached clients.

Which issue(s) this PR fixes:
Part of #2822

Special notes for your reviewer:

c7bd017 is a prefactoring of the extension helper funcs, that is necessary for making the components ready for a cached client (see commit message for more details/reasoning).
The other commits perform the actual refactoring/adaption per component.

/squash

Release note:


@timebertt timebertt requested a review from a team as a code owner May 11, 2021 09:52
@gardener-robot gardener-robot added area/dev-productivity Developer productivity related (how to improve development) area/scalability Scalability related kind/cleanup Something that is not needed anymore and can be cleaned up merge/squash size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels May 11, 2021
@rfranzke
Copy link
Member

/assign

@timebertt
Copy link
Member Author

@ialidzhikov, this is the bigger refactoring I was talking about earlier.
Let's see how the review goes and if we have enough time left to validate it before the release is cut, we can include it, otherwise it doesn't hurt to wait a bit :)

@timebertt
Copy link
Member Author

Strange...
The verify step failed twice with the following error:

Summarizing 1 Failure:

[Fail] extensions #WaitUntilExtensionObjectReady [It] should set passed object to latest state once ready 
/go/src/github.com/gardener/gardener/pkg/extensions/customresources_test.go:214

Ran 40 of 40 Specs in 0.165 seconds
FAIL! -- 39 Passed | 1 Failed | 0 Pending | 0 Skipped

Though locally, in can't get the test to fail:

$ stress ./pkg/extensions/extensions.test
343 runs so far, 0 failures
696 runs so far, 0 failures
1016 runs so far, 0 failures
1320 runs so far, 0 failures
1603 runs so far, 0 failures
1891 runs so far, 0 failures
2166 runs so far, 0 failures
2441 runs so far, 0 failures
2702 runs so far, 0 failures
2946 runs so far, 0 failures

rfranzke
rfranzke previously approved these changes May 12, 2021
Copy link
Member

@rfranzke rfranzke left a comment

Choose a reason for hiding this comment

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

/lgtm

Well done!

@timebertt
Copy link
Member Author

Thanks @rfranzke for your review, PTAL :)

For the reasons explained in gardener#4057, MergePatchOrCreate is not safe to use
without reading objects from the API server / cache first. Ideally we would
switch to server-side apply to simplify such operations on controlled objects
(e.g. extension resources), though we cannot leverage it for now because of
several issues described in gardener#4122.
As described in gardener#4057, *PatchOrCreate is easy to use incorrectly.
Remove *PatchOrCreate funcs in order to minimize the risk of misuse.
There might still be good use cases for this mechanism, though they
are limited. If there is such a good use case, we can use it also
without a helper func.
@timebertt
Copy link
Member Author

Some MergePatchOrCreate usages in this PR need to be changed, because of the reasons explained in #4057.
I will rebase the PR onto #4057 and adapt accordingly, once it's merged.

Rebased the PR and added two more commits to make it ready again:

  • one to switch from MergePatchOrCreate to GetAndCreateOrMergePatch: 3576fd6
  • and one to Remove the *PatchOrCreate funcs: 9cabff7

/unassign
/unhold
/remove status/author-action

@rfranzke PTAL :)

Copy link
Member

@rfranzke rfranzke left a comment

Choose a reason for hiding this comment

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

/lgtm

@rfranzke
Copy link
Member

rfranzke commented Jun 1, 2021

@timebertt What about the CreateOr{Strategic}MergePatch function (ref)? Do you think their current usage is safe or should it be adapted as well (i.e., first try Create, but if the resource already exists, then we Get it and Patch it afterwards)?

@rfranzke rfranzke merged commit 2e0ba2a into gardener:master Jun 1, 2021
@timebertt timebertt deleted the cleanup/directclient-5 branch June 1, 2021 08:43
@timebertt
Copy link
Member Author

@timebertt What about the CreateOr{Strategic}MergePatch function (ref)? Do you think their current usage is safe or should it be adapted as well (i.e., first try Create, but if the resource already exists, then we Get it and Patch it afterwards)?

Generally, the same applies to CreateOr{Strategic}MergePatch as to the *PatchOrCreate logic: if you're not trying to remove any optional fields in the patch, it's safe to use without doing a Get before. But if you do want to remove optional fields you have to fetch the object first, so that the diff contains an explicit null value.

So for example, this usage needs to be adapted, as labels that were removed from the seed template won't be removed from the seed itself:

seed.Labels = utils.MergeStringMaps(managedSeed.Spec.SeedTemplate.Labels, map[string]string{

Probably, adapting the helper func to do a Get before Patch wouldn't hurt. But I haven't checked all the usages in detail. Though, such a helper func brings a good chance of misuse (that's why I removed the *PatchOrCreate funcs).

@rfranzke
Copy link
Member

rfranzke commented Jun 1, 2021

OK, thanks. For the sake of simplicity and prevention of coding bugs, I'd vote for changing the function in all cases as described above (create->get->patch) instead of (create->patch). Do you agree?

@timebertt
Copy link
Member Author

Yes, I agree. That seems to be the more sustainable approach.

krgostev pushed a commit to krgostev/gardener that referenced this pull request Apr 21, 2022
* Cleanup unused/dead code

* Make EXPECTPatch easier to debug

* Refactor extensions helper funcs

This prefactoring performs several changes in the extension helper funcs:
- the funcs directly work on the passed in objects instead of creating
  new objects via separately passed newObjFuncs. Passed objects are
  expected to be filled with the latest state the controller/component
  applied/observed/retrieved, but at least namespace and name.
  This way, controllers can keep working on a single in-memory object
  instead of retrieving the same object over and over again.
- WaitUntilExtensionObjectReady additionally checks that the added
  timestamp annotation is present on the object to prevent false early
  exits when reading stale data (e.g. from a cached client).
- makes naming more consistent and clearer

This provides the following benefits:
- makes the funcs ready to be used with cached clients, as they are able
  to properly handle stale data now
- controllers/components automatically have the latest state of the
  objects present without retrieving them again from the API server.
  This will ease further refactorings and allows to safely use
  patches in a lot of cases instead of CreateOrUpdate (+RetryOnConflict).
- the funcs are easier to use and comprehend: only the desired object
  needs to be passed, no need to pass newObjFuncs, namespace and name
- the funcs are more similar to other helper funcs (e.g. CreateOrUpdate)
  and the mechanisms employed in e.g. c-r clients
- no need to pass a client.Object to postReadyFuncs which needs to be
  casted again

* Make BackupBucket controller ready for cached client

* Make BackupEntry controller/component ready for cached client

* Make ContainerRuntime component ready for cached client

* Make ControlPlane component ready for cached client

* Make Extension component ready for cached client

* Make Infrastructure component ready for cached client

* Make Network component ready for cached client

* Make OperatingSystemConfig component ready for cached client

* Make Worker component ready for cached client

* Fix failing unit test

* Address review feedback

* Switch from MergePatchOrCreate to GetAndCreateOrMergePatch

For the reasons explained in gardener#4057, MergePatchOrCreate is not safe to use
without reading objects from the API server / cache first. Ideally we would
switch to server-side apply to simplify such operations on controlled objects
(e.g. extension resources), though we cannot leverage it for now because of
several issues described in gardener#4122.

* Remove *PatchOrCreate funcs

As described in gardener#4057, *PatchOrCreate is easy to use incorrectly.
Remove *PatchOrCreate funcs in order to minimize the risk of misuse.
There might still be good use cases for this mechanism, though they
are limited. If there is such a good use case, we can use it also
without a helper func.
krgostev pushed a commit to krgostev/gardener that referenced this pull request Jul 5, 2022
* Cleanup unused/dead code

* Make EXPECTPatch easier to debug

* Refactor extensions helper funcs

This prefactoring performs several changes in the extension helper funcs:
- the funcs directly work on the passed in objects instead of creating
  new objects via separately passed newObjFuncs. Passed objects are
  expected to be filled with the latest state the controller/component
  applied/observed/retrieved, but at least namespace and name.
  This way, controllers can keep working on a single in-memory object
  instead of retrieving the same object over and over again.
- WaitUntilExtensionObjectReady additionally checks that the added
  timestamp annotation is present on the object to prevent false early
  exits when reading stale data (e.g. from a cached client).
- makes naming more consistent and clearer

This provides the following benefits:
- makes the funcs ready to be used with cached clients, as they are able
  to properly handle stale data now
- controllers/components automatically have the latest state of the
  objects present without retrieving them again from the API server.
  This will ease further refactorings and allows to safely use
  patches in a lot of cases instead of CreateOrUpdate (+RetryOnConflict).
- the funcs are easier to use and comprehend: only the desired object
  needs to be passed, no need to pass newObjFuncs, namespace and name
- the funcs are more similar to other helper funcs (e.g. CreateOrUpdate)
  and the mechanisms employed in e.g. c-r clients
- no need to pass a client.Object to postReadyFuncs which needs to be
  casted again

* Make BackupBucket controller ready for cached client

* Make BackupEntry controller/component ready for cached client

* Make ContainerRuntime component ready for cached client

* Make ControlPlane component ready for cached client

* Make Extension component ready for cached client

* Make Infrastructure component ready for cached client

* Make Network component ready for cached client

* Make OperatingSystemConfig component ready for cached client

* Make Worker component ready for cached client

* Fix failing unit test

* Address review feedback

* Switch from MergePatchOrCreate to GetAndCreateOrMergePatch

For the reasons explained in gardener#4057, MergePatchOrCreate is not safe to use
without reading objects from the API server / cache first. Ideally we would
switch to server-side apply to simplify such operations on controlled objects
(e.g. extension resources), though we cannot leverage it for now because of
several issues described in gardener#4122.

* Remove *PatchOrCreate funcs

As described in gardener#4057, *PatchOrCreate is easy to use incorrectly.
Remove *PatchOrCreate funcs in order to minimize the risk of misuse.
There might still be good use cases for this mechanism, though they
are limited. If there is such a good use case, we can use it also
without a helper func.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/dev-productivity Developer productivity related (how to improve development) area/scalability Scalability related kind/cleanup Something that is not needed anymore and can be cleaned up size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants