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

feat[compositions]: realtime compositor – part 2: changes to MRs #4637

Merged
merged 4 commits into from Oct 17, 2023

Conversation

sttts
Copy link
Contributor

@sttts sttts commented Sep 18, 2023

Description of your changes

Follow-up of #4582: also reconcile XRs when MRs change. This PR starts informers dynamically for GVRs used in XRs, including function XRs.

This feature is under the EnableRealtimeCompositions feature gate (--enable-realtime-compositions).

Design:

                    ┌─────────────────┐
                    │                 │
                    │     Manager     │
                    │                 │
                    │    ┌───────┐    │
                    │    │       │    │
                    └────┤ Cache ├────┘
                         │       │
                         └───▲───┘◄─────┬──────────┬───────────────────┐
                             │          │          │                   │
                    ┌────────┴────────┐ │ ┌────────┴────────┐ ┌────────┴────────┐
       ┌────────────┤ APIExtensions   │ │ │ APIExtensions   │ │ APIExtensions   │
       │ Composed   │ Definition      │ │ │ Compositions    │ │ Offered         │
┌──────┤ Resource   │ Controller      │ │ │ Controller      │ │ Controller      │ ...
│      │ Informers  │                 │ │ │                 │ │                 │
│      └─────┬──────┤  ┌───────────┐  │ │ │                 │ │                 │
│    creates │      └──┤           ├──┘ │ └─────────────────┘ └─────────────────┘
│  & deletes │         │ GVK Routed│    │
│     ┌──────▼────┐    │ Cache     ├────┘
│     │ Composed  │◄───┤           │fallback
│     │ Resource  │ N:1└─────▲─────┘
│     │ Cache     │          │
│     └───────────┘          │
│                            │ N:1 (dynamically started when an XRD changes)
│                   ┌────────┴────────┐
│                   │ APIExctensions  │
│ informs about gvks│ Composite       │
└───────────────────┤ Controller      │
                    │                 │
                    │                 │
                    └─────────────────┘

tl/dr:

  1. the APIExtensions definitions controller (which spawns the composite controllers dynamically through the controller engine), maintains a dynamic set of cached (= informers) per gvk.
  2. The composite controllers report (via the KindObserver interface) to the definition controller which GVKs the referenced objects have. For those, the "composedResourceInformers" (part of the definition controller) will start informers as part of a cache.
  3. When those caches become synced, they are registered in the GVK-routed cache as delegates. From that moment on that cache serves those objects. The composite controllers use that GVK-routed-cache for their lookups.
  4. Last but not least the "composedResourceInformers" distributes events of changed composed resources to the right composite controllers. For that, an index is added to the XR informer by GVK of the referenced object of each XR instance. Through that it is efficient to find the right XRs for every event.

I have:

  • Read and followed Crossplane's contribution process.
  • Added or updated unit and E2E tests for my change.
  • Run make reviewable to ensure this PR is ready for review.
  • Added backport release-x.y labels to auto-backport this PR, if necessary.
  • Opened a PR updating the docs, if necessary.

@sttts sttts requested review from turkenh and a team as code owners September 18, 2023 12:05
@sttts sttts requested a review from ytsarev September 18, 2023 12:05
@sttts sttts marked this pull request as draft September 18, 2023 12:06
@sttts sttts force-pushed the sttts-realtime-compositions-resources branch from f0fb10b to b0f0ed8 Compare September 18, 2023 12:17
@negz
Copy link
Member

negz commented Sep 18, 2023

Adding a reference to #4316, which I think is related.

@sttts sttts force-pushed the sttts-realtime-compositions-resources branch from b0f0ed8 to 5858c89 Compare September 20, 2023 14:06
@sttts sttts changed the title WIP: realtime composition for MRs feat[compositions]: realtime compositor – part 2: changes to MRs Sep 20, 2023
@sttts sttts force-pushed the sttts-realtime-compositions-resources branch 4 times, most recently from 3642e40 to a0e8a69 Compare September 20, 2023 14:48
@sttts sttts force-pushed the sttts-realtime-compositions-resources branch 2 times, most recently from ba73b18 to 3197040 Compare October 5, 2023 09:09
@sttts sttts marked this pull request as ready for review October 5, 2023 09:10
@sttts sttts requested a review from negz as a code owner October 5, 2023 09:10
@sttts sttts force-pushed the sttts-realtime-compositions-resources branch 12 times, most recently from 10c91b7 to b74ec8d Compare October 10, 2023 08:46
@sttts sttts force-pushed the sttts-realtime-compositions-resources branch 8 times, most recently from 43bfdb7 to 4e3fd74 Compare October 16, 2023 13:37
for _, ref := range xr.GetResourceReferences() {
gvks = append(gvks, ref.GroupVersionKind())
}
r.kindObserver.WatchComposedResources(gvks...)
Copy link
Contributor

Choose a reason for hiding this comment

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

if we now watch composed resources and trigger the reconcile in realtime, should we stop ending the loop with:

return reconcile.Result{RequeueAfter: r.pollInterval}, errors.Wrap(r.client.Status().Update(ctx, xr), errUpdateStatus)

and do instead:

return reconcile.Result{}, errors.Wrap(r.client.Status().Update(ctx, xr), errUpdateStatus)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can't I guess. 1. environments 2. functions relying on 60s poll.

Should we do everything towards removing poll? Yes, please. @negz

Copy link
Contributor

Choose a reason for hiding this comment

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

if environment feature is not enabled and composition is not based on functions, then we could? Also, we could watch environment for changes using the same WatchComposeResource approach, but keep in memory relationships between environments and compositions, to know later what composition to reconcile.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Am not against that direction, quite the opposite. Worth an attempt in a follow-up to see how far we get (in e2e).

For functions, I would like to see us being explicit that there is no 60s poll guarantee. Maybe we need an API to ask for one if necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That will be step 3: #4822

@sttts sttts force-pushed the sttts-realtime-compositions-resources branch from 4e3fd74 to 7cf75af Compare October 17, 2023 07:43
@@ -53,6 +69,9 @@ func TestCompositionMinimal(t *testing.T) {
)).
Assess("CreateClaim", funcs.AllOf(
funcs.ApplyResources(FieldManager, manifests, "claim.yaml"),
funcs.InBackground(funcs.LogResources(nopList)),
Copy link
Contributor

Choose a reason for hiding this comment

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

how is this change related to the work done in this PR? I looks like a leftover of some debugging?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These tests run under realtime composition as well. And in general, I would like us to have this kind of output to understand the core mechanisms at play in such a test. Hence, I added it also here. There are very likely more places where we need visibility of the main flow of a test.

)).
Assess("CreateClaim", funcs.AllOf(
funcs.ApplyResources(FieldManager, manifests, "claim.yaml"),
funcs.InBackground(funcs.LogResources(nopList, withTestLabels)),
Copy link
Contributor

Choose a reason for hiding this comment

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

InBackground calls are for debugging? Could we make them implicit, for example call them within ApplyResource, so that all tests can automatically have benefits?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not (only) for debugging. For visibility of the core mechanism at play in a test.

We cannot do these automatically as e.g. ApplyResources has no knowledge about what happens with those resources, i.e. the related resources they spawn.

Copy link
Contributor

Choose a reason for hiding this comment

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

ApplyResource could become a bit smarter and understand that we are applying claim, and then via references follow to composite and MRs, or?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

PR welcome for an automatic related object tracker :-)

Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.io>
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.io>
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.io>
Signed-off-by: Dr. Stefan Schimanski <stefan.schimanski@upbound.io>
@sttts sttts force-pushed the sttts-realtime-compositions-resources branch from 7cf75af to 2348236 Compare October 17, 2023 12:37
@negz negz merged commit 5bb2284 into crossplane:master Oct 17, 2023
17 checks passed
Copy link
Contributor

@phisco phisco left a comment

Choose a reason for hiding this comment

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

This should also delete the claim first and then check all nop resources have been deleted, no?

negz added a commit to negz/crossplane that referenced this pull request Feb 1, 2024
This was removed in crossplane#4637,
with the options instead passed as a 'first-class' argument.

I don't think these need to be a first-class argument. This reverts to
the old behaviour, which matches the claim 'offered' controller.

I noticed this asymmetry while reminding myself how feature flags are
plumbed down to the offered and definition controllers. The former is
responsible for managing claim controllers, the latter XR controllers.

Signed-off-by: Nic Cope <nicc@rk0n.org>
negz added a commit to negz/crossplane that referenced this pull request Feb 1, 2024
This was removed in crossplane#4637,
with the options instead passed as a 'first-class' argument.

I don't think these need to be a first-class argument. This reverts to
the old behaviour, which matches the claim 'offered' controller.

I noticed this asymmetry while reminding myself how feature flags are
plumbed down to the offered and definition controllers. The former is
responsible for managing claim controllers, the latter XR controllers.

Signed-off-by: Nic Cope <nicc@rk0n.org>
negz added a commit to negz/crossplane that referenced this pull request Feb 1, 2024
This was removed in crossplane#4637,
with the options instead passed as a 'first-class' argument.

I don't think these need to be a first-class argument. This reverts to
the old behaviour, which matches the claim 'offered' controller.

I noticed this asymmetry while reminding myself how feature flags are
plumbed down to the offered and definition controllers. The former is
responsible for managing claim controllers, the latter XR controllers.

Signed-off-by: Nic Cope <nicc@rk0n.org>
negz added a commit to negz/crossplane that referenced this pull request Feb 1, 2024
This was removed in crossplane#4637,
with the options instead passed as a 'first-class' argument.

I don't think these need to be a first-class argument. This reverts to
the old behaviour, which matches the claim 'offered' controller.

I noticed this asymmetry while reminding myself how feature flags are
plumbed down to the offered and definition controllers. The former is
responsible for managing claim controllers, the latter XR controllers.

Signed-off-by: Nic Cope <nicc@rk0n.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants