fix(ros2): resolve borrow conflict in publish_one
This commit is contained in:
+25
-15
@@ -254,12 +254,19 @@ impl TinesNode {
|
|||||||
self.ensure(&tines_topic)?;
|
self.ensure(&tines_topic)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish the latest observation for every managed topic.
|
// Publish the latest observation for every managed topic. We only need
|
||||||
let managed: Vec<String> = self.managed.keys().cloned().collect();
|
// each topic's `tines_topic` bytes to look up its latest observation,
|
||||||
for name in managed {
|
// so clone them (and the name) into owned locals *before* calling
|
||||||
if let Some(topic) = self.managed.get_mut(&name) {
|
// `publish_one`. That drops the borrow of `self.managed` up front —
|
||||||
self.publish_one(&topic.tines_topic, name, now)?;
|
// holding `&mut self.managed` across the `&mut self` call is the
|
||||||
}
|
// sibling of the E0502 the reviewer flagged.
|
||||||
|
let managed: Vec<(String, Vec<u8>)> = self
|
||||||
|
.managed
|
||||||
|
.iter()
|
||||||
|
.map(|(name, t)| (name.clone(), t.tines_topic.clone()))
|
||||||
|
.collect();
|
||||||
|
for (name, tines_topic) in managed {
|
||||||
|
self.publish_one(&tines_topic, name, now)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -272,20 +279,23 @@ impl TinesNode {
|
|||||||
name: String,
|
name: String,
|
||||||
now: Tick,
|
now: Tick,
|
||||||
) -> Result<(), TinesNodeError> {
|
) -> Result<(), TinesNodeError> {
|
||||||
let topic = self
|
// `latest_obs` takes `&self`, but `topic` below would hold a live
|
||||||
.managed
|
// `&mut self.managed` — the E0502 the reviewer flagged. Collect the
|
||||||
.get_mut(&name)
|
// latest observation on an immutable borrow that ends here, then take
|
||||||
.expect("managed topic still present");
|
// `&mut self.managed` for only the publish + bookkeeping that follows.
|
||||||
if let (Some(publisher), Some(obs)) =
|
let Some(obs) = self.latest_obs(tines_topic, now) else {
|
||||||
(topic.publisher.as_mut(), self.latest_obs(tines_topic, now))
|
return Ok(());
|
||||||
{
|
};
|
||||||
|
if let Some(topic) = self.managed.get_mut(&name) {
|
||||||
if topic.last_pub == Some(obs.id()) {
|
if topic.last_pub == Some(obs.id()) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let payload = String::from_utf8_lossy(&obs.payload).into_owned();
|
let payload = String::from_utf8_lossy(&obs.payload).into_owned();
|
||||||
let msg = StrMsg { data: payload };
|
let msg = StrMsg { data: payload };
|
||||||
let _ = publisher.publish(&msg);
|
if let Some(publisher) = topic.publisher.as_mut() {
|
||||||
topic.last_pub = Some(obs.id());
|
let _ = publisher.publish(&msg);
|
||||||
|
topic.last_pub = Some(obs.id());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user