Skip to content

Conversation

@Schmarni-Dev
Copy link

the current implementation of object destruction causes issues if all interfaces are removed on an object that has a child with interfaces, this pr fixes that by only destroying objects if they don't have children, and cleaning up any parents that no longer have children

Signed-off-by: Schmarni <marnistromer@gmail.com>
@zeenix
Copy link
Contributor

zeenix commented Oct 21, 2025

Thanks for the PR. I'm going on vacation for a week so I will likely only be able to look into this next week.

@codspeed-hq
Copy link

codspeed-hq bot commented Oct 21, 2025

CodSpeed Performance Report

Merging #1553 will not alter performance

Comparing Schmarni-Dev:better_obj_destruct (c83f3d2) with main (833dd31)

Summary

✅ 22 untouched

Comment on lines -104 to +110
!self.interfaces.keys().any(|k| {
(!self.interfaces.keys().any(|k| {
*k != Peer::name()
&& *k != Introspectable::name()
&& *k != Properties::name()
&& *k != ObjectManager::name()
})
})) && self.children.is_empty()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this change is about fixing the logic of "is this node empty" while the other changes aren't related to this fix? If so, could we please split the commit? It will also make it easier for me to review the changes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this change is about fixing the logic of "is this node empty" while the other changes aren't related to this fix?

Right, reading up the PR description, the other changes seems to be related but still a separate change: removing all empty nodes above the node being removed.

Copy link
Contributor

@zeenix zeenix left a comment

Choose a reason for hiding this comment

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

Also, please add description/rationale to the commit messages too (not just the PR).

Comment on lines +225 to +226
if let Some(manager_path) = manager_path.clone() {
let ctxt = SignalEmitter::new(&self.connection(), manager_path.clone())?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we keep cloning the manager_path? 🤔 Pretty sure we don't need to do that for if let ... statements at least.

Comment on lines +204 to +215
fn gen_paths(paths: &mut Vec<(ObjectPath<'_>, String)>, path: ObjectPath<'_>) {
if path.is_empty() {
return;
}
let mut path_parts = path.rsplit('/').filter(|i| !i.is_empty());
let last_part = path_parts.next().unwrap();
let ppath = ObjectPath::from_string_unchecked(
path_parts.fold(String::new(), |a, p| format!("/{p}{a}")),
);
paths.push((ppath.clone(), last_part.to_owned()));
gen_paths(paths, ppath);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

That's potentially a lot of allocations. I'm confident we don't need them. We can parse the path as we traverse the hierarchy.

if !node.is_empty() {
break;
}
let interfaces = node.interfaces().cloned().collect::<Vec<_>>();
Copy link
Contributor

Choose a reason for hiding this comment

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

why are we cloning here?

@zeenix
Copy link
Contributor

zeenix commented Dec 6, 2025

@Schmarni-Dev so you think you'll be able to finish this?

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.

2 participants