J'ai le code suivant :
use std::error::Error;
use std::collections::HashMap;
use std::fmt::{Display, Formatter, Error as FmtError};
use std::sync::{Arc, Mutex};
use std::thread;
use amiquip::{ConsumerMessage};
use serde::Deserialize;
use crate::rabbit_mq;
use crate::rabbit_mq::RmqChannel;
use super::agv::*;
pub type AGVControllerError = Box<dyn Error + Send + Sync + 'static>;
pub type AGVControllerResult<T> = Result<T, AGVControllerError>;
pub struct AGVController<'a> {
agv_map: HashMap<&'a str, AGV>,
//rmq: &'a mut rabbit_mq::RMQ
rmq: Arc<Mutex<rabbit_mq::RMQ>>
}
impl<'a> AGVController<'a> {
// Create a new AGV Controller
//pub fn new(rmq: &'a mut rabbit_mq::RMQ) -> Self {
pub fn new(rmq: Arc<Mutex<rabbit_mq::RMQ>>) -> Self {
Self {
agv_map: HashMap::new(),
rmq
}
}
// Listen for messages related to the agv controller.
pub fn listen(&'static mut self, routing_key: &'static str) -> AGVControllerResult<()> {
let mut rmq_channel = self.rmq.lock().unwrap().create_channel()?;
thread::spawn(move || {
//TODO: need to handle any error returned here
//listen_on_consumer(routing_key, rmq_channel).unwrap();
let consumer = rmq_channel.create_consumer(routing_key).unwrap();
let test = self.agv_map.get("rr");
for (i, message) in consumer.receiver().iter().enumerate() {
match message {
ConsumerMessage::Delivery(delivery) => {
let body = String::from_utf8_lossy(&delivery.body);
println!("({:>3}) Received [{}]", i, body);
consumer.ack(delivery).unwrap();
}
other => {
println!("Consumer ended: {:?}", other);
break;
}
}
}
});
return Ok(());
}
}
Dans la fonction d'écoute, je crée un consommateur de rmq et je lis les messages au fur et à mesure qu'ils arrivent. Tout cela fonctionne bien. Mais lorsqu'un message est lu, j'ai besoin d'accéder aux informations, données et fonctions de la structure. Faire en sorte que le paramètre self utilise 'static' semble régler le problème. Est-ce correct ? static signifie qu'il reste en vie aussi longtemps que le programme existe, n'est-ce pas ? Ce qui semble correct puisque je veux qu'il soit vivant tant que le fil de discussion est en cours. Je veux juste m'assurer que je fais cela correctement.
UPDATE :
J'ai donc essayé de me cloner et de l'utiliser dans le fil de discussion mais j'obtiens :
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/agv/agv_controller.rs:47:35
|
47 | let mut self_clone = self.clone();
| ^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
--> src/agv/agv_controller.rs:35:6
|
35 | impl<'a> AGVController<'a> {
| ^^
note: ...so that the types are compatible
--> src/agv/agv_controller.rs:47:35
|
47 | let mut self_clone = self.clone();
| ^^^^^
= note: expected `&agv_controller::AGVController<'_>`
found `&agv_controller::AGVController<'a>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src/agv/agv_controller.rs:48:23: 66:10]` will meet its required lifetime bounds...
--> src/agv/agv_controller.rs:48:9
|
48 | thread::spawn(move || {
| ^^^^^^^^^^^^^
note: ...that is required by this bound
--> /Users/conordowney/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/mod.rs:646:15
|
646 | F: Send + 'static,
| ^^^^^^^