Skip to content

Set observed gen in gen-reconciler#1261

Closed
whaught wants to merge 2 commits into
knative:masterfrom
whaught:genreconciler
Closed

Set observed gen in gen-reconciler#1261
whaught wants to merge 2 commits into
knative:masterfrom
whaught:genreconciler

Conversation

@whaught
Copy link
Copy Markdown
Contributor

@whaught whaught commented Apr 29, 2020

Issue #1226

Automatically bump ObservedGeneration in the generated reconciler and set status to unknown for unhandled errors.

looks for // +genducklogic to run this part of the code generation. This can serve as a jumping-off point to share other arbitrary logic among duck-type shaped resources.

@knative-prow-robot knative-prow-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 29, 2020
@googlebot googlebot added the cla: yes Indicates the PR's author has signed the CLA. label Apr 29, 2020
@knative-prow-robot knative-prow-robot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Apr 29, 2020
@whaught whaught changed the title [WIP} Set observed gen in gen-reconciler [WIP] Set observed gen in gen-reconciler Apr 29, 2020
@knative-prow-robot knative-prow-robot removed the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Apr 29, 2020
@knative-prow-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: whaught
To complete the pull request process, please assign n3wscott
You can assign the PR to them by writing /assign @n3wscott in a comment when ready.

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

Details 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

@knative-prow-robot knative-prow-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Apr 29, 2020
@whaught whaught changed the title [WIP] Set observed gen in gen-reconciler Set observed gen in gen-reconciler Apr 30, 2020
@knative-prow-robot knative-prow-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 30, 2020
@whaught
Copy link
Copy Markdown
Contributor Author

whaught commented Apr 30, 2020

/assign @n3wscott @mattmoor

@antoineco
Copy link
Copy Markdown
Contributor

antoineco commented May 1, 2020

I like the idea but have 2 suggestions:

  • Make that behavior part of every reconciler instead of being opt-in. We don't require devs to decide whether they want the reconciler to call UpdateStatus on their behalf, so why would they decide to disable just those extra initializations? I think people who want the flexibility won't use reconciler-gen anyway.
  • If we insist on making it opt-in, please make your change in the existing tag (+genreconciler:initstatus=true, false if missing). That would avoid clutter and I think it's generally a better UX.

Copy link
Copy Markdown
Contributor

@n3wscott n3wscott left a comment

Choose a reason for hiding this comment

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

I wonder if this generated code belongs inside of the api and not the reconciler. If the reconciler can test that the resource under reconciliation implements some PostReconcile method that does the cleanups and testing, then you can use the correct condition sets and/or add a Mark* method to enable the interactions you are looking for.


// +genclient
// +genreconciler
// +genducklogic
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the only thing is that duck == interface, so geninterfacelogic does not make a ton of sense.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I won't pretend to be good at naming. I'm not sure I see the interface problem. The idea was "generate duck-type shaped common logic".

Can you suggest an alternative? @antoineco also suggested making it another option on +genreconciler if you have any thoughts on that (although that already has a :classname option)

}
}

{{if .genDuckLogic}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the code will get here for deleted resources as well and it is not allowed to update generation for a deleted object

rc := resource.Status.GetCondition(apis.ConditionReady)
// if a new generation is observed and reconciliation reported an error event
// the reconciler should change the ready state. By default we will set unknown.
if equality.Semantic.DeepEqual(originalRc, rc) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

but this could be that it went from ready true to ready true if the update was something minor

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This only runs if reconcileEvent != nil should we should be in a (potential) error case.

// the reconciler should change the ready state. By default we will set unknown.
if equality.Semantic.DeepEqual(originalRc, rc) {
logger.Warnw("A reconconiler observed a new generation without updating the resource status")
condSet.Manage(&resource.Status).MarkUnknown(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think you should change the ready condition directly. It needs a dependent condition that cases the unreadiness.

@whaught
Copy link
Copy Markdown
Contributor Author

whaught commented May 1, 2020

I like the idea but have 2 suggestions:

  • Make that behavior part of every reconciler instead of being opt-in. We don't require devs to decide whether they want the reconciler to call UpdateStatus on their behalf, so why would they decide to disable just those extra initializations? I think people who want the flexibility won't use reconciler-gen anyway.
  • If we insist on making it opt-in, please make your change in the existing tag (+genreconciler:initstatus=true, false if missing). That would avoid clutter and I think it's generally a better UX.

The reason this isn't part of every reconciler is because not ever reconciler follows the duck-type code shape. Specifically some eventing resources don't have observed generation and this code fails for those.

The reason this is opt-in is partly to allow to allow generating for non-duck resource but also for safety as we switch to it. I want to migrate resources to it one-by one by adding this tag and removing their reconciler's handling of observed gen. This will let me test it safely as I go through that process. Unfortunately +genreconciler:classname is already a thing to allow reconcilers the option of specifying a type to reconciler. Adding more options to that tag might get pretty cluttered (we could comma separate them).

@antoineco
Copy link
Copy Markdown
Contributor

@whaught that's a fair point, I didn't consider not every type implements these.

If the tag's elements are key=value separated by colons, I think we should be safe adding new parameters to it.

@whaught
Copy link
Copy Markdown
Contributor Author

whaught commented May 1, 2020

@whaught that's a fair point, I didn't consider not every type implements these.

If the tag's elements are key=value separated by colons, I think we should be safe adding new parameters to it.

The tags are not key=value. You can read the parsing here:

func extractReconcilerClassTag(t *types.Type) (string, bool) {

it currently expects "genreconciler:class". We could change this and then go update existing usages of it, make it key value, and comma separate multiple tags. I'm not sure if this is really a worthy migration in the scope of what this PR is trying to accomplish for the cost of just adding a new tag.

@antoineco
Copy link
Copy Markdown
Contributor

antoineco commented May 1, 2020

@whaught the current expected format is +genreconciler:class=<class>, which looks to me like a format that could very easily accept new parameters separated by colon or commas. Here are two examples:

+genreconciler:class=eventing.knative.dev/broker.class,initstatus=true
+genreconciler:class=eventing.knative.dev/broker.class:initstatus=true

Besides, there are at most 4 types that currently set this class parameter in the code base.

I simply can't see a case for a new tag here, but I'm also happy to be proven wrong.

@whaught
Copy link
Copy Markdown
Contributor Author

whaught commented May 1, 2020

@antoineco you're right about the existing format. Although a parser would need to be written to allow for other options. The argument is merely that a new tag doesn't cost anything and allows for options of its own. This isn't intended to be the only common generated logic, but a starting point.

The existing pattern in k8s which is being invoked is here:


you'll see that k8s doesn't expect implementors to be using comment tags this way. We sort of cheat by looking for the hardcoded tag "+genreconciler:class"

In the future I hope to be able to include other common factors like initializing defaults/conversions and common metrics on conditions.
Eventually I was forseeing something like +genducklogic:observegen=true,commonmetrics=true,initdefaults=true

Just thought it might get cluttered, and in line with what @n3wscott said, these aren't properties of a reconciler (which makes no resource shape assumptions) but are properties of the API duck resource.

I'm happy to go the other way on this if folks are passionate.

@whaught
Copy link
Copy Markdown
Contributor Author

whaught commented May 1, 2020

/hold I'm working on hacking together a potential alternative to this

@knative-prow-robot knative-prow-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label May 1, 2020
@whaught
Copy link
Copy Markdown
Contributor Author

whaught commented May 4, 2020

/close

pulled this logic into #1284 with an interface that makes it more easily testable

@knative-prow-robot
Copy link
Copy Markdown
Contributor

@whaught: Closed this PR.

Details

In response to this:

/close

pulled this logic into #1284 with an interface that makes it more easily testable

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.

@knative-prow-robot knative-prow-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 4, 2020
@knative-prow-robot
Copy link
Copy Markdown
Contributor

@whaught: PR needs rebase.

Details

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.

@whaught whaught deleted the genreconciler branch May 7, 2020 00:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla: yes Indicates the PR's author has signed the CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants