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

Decouple Meta from k8s-openapi #385

Merged
merged 2 commits into from
Mar 17, 2021
Merged

Decouple Meta from k8s-openapi #385

merged 2 commits into from
Mar 17, 2021

Conversation

MikailBag
Copy link
Contributor

@MikailBag MikailBag commented Jan 15, 2021

This PR changes kube::api::Meta so that it no longer depends on k8s-openapi.

TODO:
debug generic_watcher not working (upd: fixed)

@MikailBag MikailBag changed the title Meta Decouple Meta from k8s-openapi Jan 15, 2021
Copy link
Member

@clux clux left a comment

Choose a reason for hiding this comment

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

There's a good idea at the core of this that can make DynamicResource usable. Left some comments on the new Meta trait, there is some work needed there IMO. That said, thanks a lot for this. You've found a huge lack in DynamicResource, which is worth raising a bug about as well.

/// Types that know their metadata at compile time should select `Family = ()`.
/// Types that require some information at runtime should select `Family`
/// as type of this information.
type Family: Send + Sync + 'static;
Copy link
Member

Choose a reason for hiding this comment

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

This is the crux of the PR. We are changing the Meta trait to basically be our own, more practical, Resource trait. I think that overall is positive; DynamicResource, as you pointed out, just could not work in more than trivial situations without this change, and a blanket implementation of our trait of k8s_openapi::Resource + Metadata objects is - in theory - easy to do.

A rename of the trait is probably in order to reflect what the trait now does. Not sure to what though.

The Family type parameter here is definitely the most awkward implementation detail of the trait though. Ideally, I would like to avoid this, as it's making breaking changes to both kube::Resource and kube::Api (as well as making them more awkward).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Regarding naming, Do you think the following makes sense?

  • rename Meta to Resource
  • rename Resource to RequestBuilder/QueryBuilder
  • rename Family to RuntimeTypeInformation (long name, but anyway users will rarely interact with it)

I tried to make sure that kube::Api public API was not modified (if K has all necessary information at compile-time, Api::all and Api::namepsaced are still provided). Did I miss something? I will also add similar backward-compatible constructors to the Resource.

Copy link
Member

Choose a reason for hiding this comment

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

I think this has a lot more potential now that it's shown that we don't need to break Api or Resource, although I will leave some comments on the implementation inlined elsewhere.

Let's not worry about the names of those three yet (it'll make it super confusing to review, so we can change them later). Although I think in theory the first two are fine.

Copy link
Member

@clux clux left a comment

Choose a reason for hiding this comment

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

some high level comments / questions

Static(&'static str),
/// Should be used when string is only known at runtime
Dynamic(Arc<str>),
}
Copy link
Member

Choose a reason for hiding this comment

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

This string wrapper does feel like a pretty complicated thing to expose in an interface. Could you explain what it's trying to optimise for? The Arc in there feels particularly confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's purely an optimization to make cloning less expensive, especially when GVK is known at compile-time.

Do you think it should be replaced by a plain String?

Copy link
Member

Choose a reason for hiding this comment

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

If it's only a handful of strings that gets cloned once, then I would worry more about the prettiness of the api more, if it's happening all the time, then it's definitely a reasonable optimization.

I think it's probably a smart thing to do internally (now that GVK has a simpler constructor), but I don't think we should expose StringRef to the world.

Also, curious to the tradeoff of Arc<str> vs just String inside Dynamic. It feels like this would just be a ref to the apps' owned String, with atomic because it's used in threads? Maybe we can use Into<String> in the constructor and turn it to a String in the enum instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll change StringRef to be private (as well as GVK fields) and provide two constructors (static and dynamic) instead.

kube/src/api/dynamic.rs Show resolved Hide resolved
};

let client = Client::try_default().await?;
let api = Api::<DynamicObject>::all_with(client, &erased_kind);
Copy link
Member

@clux clux Jan 28, 2021

Choose a reason for hiding this comment

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

Not sure if this is achievable, but ideally, I feel like this could look like:

let gvk = GroupVersionKind::group(group).version(version).kind(kind);
let api: Api<DynamicObject> = gvk.into_api(client);

which looks very similar to the current DynamicResource, so maybe you don't need the separate ErasedKind (or GroupVersionKind as i suggested calling it).
Don't worry about breaking DynamicResource; it already doesn't work.

@clux
Copy link
Member

clux commented Jan 28, 2021

This is now touching on a lot of the questions posed in #292 so maybe @teozkr has some thoughts on this as well.

@MikailBag
Copy link
Contributor Author

By the way, it seems that CI does not check that kube is able to compile without warnings.

{
stream
.map_ok(move |obj| stream::iter(mapper(obj).into_iter().map(Ok)))
.try_flatten()
}

/// Enqueues the object itself for reconciliation
pub fn trigger_self<S>(stream: S) -> impl Stream<Item = Result<ObjectRef<S::Ok>, S::Error>>
pub fn trigger_self<S, F>(stream: S, family: F) -> impl Stream<Item = Result<ObjectRef<S::Ok>, S::Error>>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is slight breakage in a low-level API. Do you think it's OK not to provide separate trigger_self and trigger_self_with functions?

Copy link
Member

Choose a reason for hiding this comment

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

Personally, yes. I think this is ok.

@MikailBag
Copy link
Contributor Author

Seems that the automatic merge has broken things a bit. I will rebase on the master.

Copy link
Member

@clux clux left a comment

Choose a reason for hiding this comment

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

Left only a few tiny nits. It's a complex one, and sorry it's taken me this long to get to it, but it is really appreciated.

{
stream
.map_ok(move |obj| stream::iter(mapper(obj).into_iter().map(Ok)))
.try_flatten()
}

/// Enqueues the object itself for reconciliation
pub fn trigger_self<S>(stream: S) -> impl Stream<Item = Result<ObjectRef<S::Ok>, S::Error>>
pub fn trigger_self<S, F>(stream: S, family: F) -> impl Stream<Item = Result<ObjectRef<S::Ok>, S::Error>>
Copy link
Member

Choose a reason for hiding this comment

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

Personally, yes. I think this is ok.

examples/generic_watcher.rs Outdated Show resolved Hide resolved
examples/generic_watcher.rs Outdated Show resolved Hide resolved
kube-runtime/src/controller/mod.rs Show resolved Hide resolved
kube/src/api/dynamic.rs Show resolved Hide resolved
@clux
Copy link
Member

clux commented Mar 15, 2021

Seems that the automatic merge has broken things a bit. I will rebase on the master.

Sorry, I tried to resolve conflicts last nights, thought I did it. The conflicts were all around type parameters where I had added Debug requirements in the interim.

@clux clux merged commit 813da82 into kube-rs:master Mar 17, 2021
@clux
Copy link
Member

clux commented Mar 17, 2021

Finally merged! Thanks a lot for all the work here :D
Have documented the huge change in the changelog

I did discover one small p'tietoau quirk in #464. so will hold off on the release for a little bit while thinking about it, but it's pretty minor, and non-blocking. However, if you have time to look it'd be really appreciated.

@kazk
Copy link
Member

kazk commented Mar 17, 2021

Before releasing, I think we should discuss renaming the associated type Family and traits as suggested above.

For the changelog, I think we should briefly mention what needs to be changed to update when it's not obvious. This also helps users to understand the scope (if they're affected or not). If I'm understanding correctly, this change doesn't affect many, but the current changelog looks intimidating because it's unclear. I think most users are unfamiliar with Meta and anything listed under that change, but it sounds too important to skip. Maybe add a note like, "you're not affected by this change unless ..."?

@clux
Copy link
Member

clux commented Mar 18, 2021

Yeah, I agree with that. I mostly wrote out the things as I saw them for myself. Wasn't even sure if many people have read this PR, as it's been silently sitting in the background for 3 months :-)

Naming. I'll open a new issue on this.

@clux clux mentioned this pull request Mar 18, 2021
clux added a commit that referenced this pull request Mar 18, 2021
@clux clux mentioned this pull request Mar 29, 2021
2 tasks
@clux
Copy link
Member

clux commented Mar 31, 2021

Released in 0.52.0 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Remove version from ObjectRef? Confusing overlap between different resource metadata types
3 participants