-
-
Notifications
You must be signed in to change notification settings - Fork 313
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
Remove dyntype
from ObjectRef
#1053
base: main
Are you sure you want to change the base?
Conversation
Ok, have done a lot of work here to help us get the type information into kube_runtime's I think it's actually possible to make the signatures involving |
Codecov Report
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more Additional details and impacted files@@ Coverage Diff @@
## main #1053 +/- ##
==========================================
- Coverage 72.76% 72.16% -0.61%
==========================================
Files 66 66
Lines 5063 5090 +27
==========================================
- Hits 3684 3673 -11
- Misses 1379 1417 +38
|
If desirable can split out the |
/// ); | ||
/// ``` | ||
#[non_exhaustive] | ||
pub struct ObjectRef<K: Resource> { | ||
pub dyntype: K::DynamicType, | ||
pub struct ObjectRef { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a fan of losing the type information here. Especially how this effectively makes it possible (and even the default!) to make a completely untyped ObjectRef
, which is ~never valid.
Treating namespace: None
as a wildcard has been problematic enough so far IMO. :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of the whole point of the PR; to pass the type information dynamically rather than statically.
I think it's a great guarantee to have it statically available, but it comes at a great cost:
Controller::owns_with
+Controller::watches_with
becomes required ways to pass the dyn info (despite theTypeMeta
always being available at runtime)- our
ObjectRef
becomes very hard to use outside of kube in a generic setting (e.g.ObjectRef
cannot even beDisplay
'd without knowledge of root type) - dyntype infects type signatures in
Writer
,Store
,ReconcileRequest
,trigger_with
further complicating our api
This complexity can be hidden by doing runtime evaluation of the the TypeMeta
. I think maybe we can make better constructors for this if the defaults are not that great for you, maybe some safer builders? I am happy to go down that avenue if this is better?
Note that I am also doing this because we need to type-erase K
from ObjectRef
to progress on the ApiResource
work needed for the v2 client work (we need Scope
on the Dyntype, and that requires refactoring the ApiResource
, which requires refactoring the ObjectRef
that uses the dyntype for equality). ..so down the line, this does aim to remove the namespace: None
problem (via client-v2).
Self { | ||
name: meta.name.clone().unwrap_or_default(), | ||
namespace: meta.namespace.clone(), | ||
types: obj.types(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not super happy about each ObjectRef
needing its own clone of all the type metadata when we know it all statically anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a lot less cloning in the dynamic case though. Before we had to clone the full dynamictype, which is a full ApiResource
. I don't see a way to be able to get type information out of dynamic types without either:
- the current complicated dynamic type feeding (which is more clone heavy on dyn types, and has more difficult ctors)
- actually cloning the typemeta for each object
I don't think it's such a big hit. It's worth it to simplify the api so we can start moving away from _with
suffixed ctors. Our reflectors are the real memory hog here that's worth optimising for imo.
namespace: None, | ||
extra: Extra::default(), | ||
types: None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OwnerReference
carries type metadata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to clean up the constructors of ObjectRef
now. Have grabbed the available information now in ObjectRef::from_owner
via OwnerReference
to provide less avenues for not putting valid information in there.
This ctor is used only by trigger_owners
to create an ObjectRef
, so using this data here means that it's possible for a user to orphan a controller owned resource by kubectl edit
ing out the ownerref of a child. Still, that is probably the right behaviour.
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
/// assert_eq!( | ||
/// ObjectRef::from_obj(&pod).within("ns"), | ||
/// ObjectRef::from_owner(&oref).within("ns"), | ||
/// ); | ||
/// assert_eq!( | ||
/// ObjectRef::from_obj(&pod).within("ns"), | ||
/// ObjectRef::from_resource::<Pod>("foo").within("ns") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have reworked the primary ctors of ObjectRef
such that there are only these three exposed (manual construction still possible) and all of these have a way of injecting the typeinfo by default.
more accurately explains what the trait is doing Signed-off-by: clux <[email protected]>
Signed-off-by: clux <[email protected]>
Signed-off-by: Eirik A <[email protected]>
Signed-off-by: Eirik A <[email protected]>
Signed-off-by: clux <[email protected]>
An experiment based on things discussed with @nightkr .
Basically, #1038 is blocked because
ObjectRef
equality is problematic when we change theDynamicType
because it affects how controllers check equality. Teo suggested to lift the dyntype concerns into the reflector and this is a WIP for that.We have added a
Inspect
trait to look upTypeMeta
at runtime (without the need for complicated associated types). This should always work except in the few pathological cases and it simplifies usage everywhere because we can blanket implement the trait for all normal cases (the two dynamic ones plus the static ones).Things to note:
Resource
trait also extended with a::typemeta
method to aid the old-style erasure inObjectRef
ObjectRef
now has a::with_types
field that plugs in typemeta (possibly viaResource::typemeta
from a static type)ObjectRef
toObjectReference
now a try_from (user might not always supply GVK data, even though we do)_with
suffixed and dynamic concerns likewatches_with
owns_with
disappear in controller/modtrigger_owners
against the owner dyntype (which is still required)ReconcileRequests
and its relied uponObjectRef
display is mostly unchanged because the GVK data is now fetched via the typemeta getterThere are also possibly more places we can kill dyntype in controller, but this is is a minimal MVP.