当调用使用redis-r创建redis连接的函数时,如何防止生存期问题



我目前正在使用redis rs来设置一个简单的redis接口,其中的一部分让我生成一个线程,该线程在循环中有一个redis订阅者来检查作业,一个最小的代码示例是

pub fn test(
queue_name: &str,
redis_url: &str,
) -> Result<std::thread::JoinHandle<()>, redis::RedisError> {
let event_subscription_handle = event_subscriber(queue_name, redis_url)?;
Ok(event_subscription_handle)
}
fn event_subscriber(
queue_name: &str,
redis_url: &str,
) -> Result<std::thread::JoinHandle<()>, redis::RedisError> {
let owned_queue_name = queue_name.to_owned();
let owned_redis_url = redis_url.to_owned();
let client = redis::Client::open(owned_redis_url)?;
let mut con = client.get_connection()?;
let mut pubsub = con.as_pubsub();
pubsub.subscribe(format!("{}", owned_queue_name))?;
Ok(std::thread::spawn(move || loop {
let msg: String = pubsub.get_message().unwrap().get_payload().unwrap();
println!("{}", msg)
}))
}

与联机

let mut pubsub = con.as_pubsub();

con上出现一个错误,称为'con' does not live long enough borrowed value does not live long enough

我只是想以一种惯用的方式来理解我应该如何处理这件事。

谢谢。

您正在函数中创建一个连接作为局部变量,然后尝试在线程中使用对它的引用。在函数调用完成后,线程将需要该引用,但变量将在函数调用结束时删除。

我想您在线程外创建连接的原因是为了在生成线程之前处理错误。

相反,由于redis::ConnectionSend,您可以做的是将连接移动到线程中,然后在线程内调用as_pubsub()。这样就不会引用线程外的内容。

fn event_subscriber(
queue_name: &str,
redis_url: &str,
) -> Result<std::thread::JoinHandle<()>, redis::RedisError> {
let owned_queue_name = queue_name.to_owned();
let mut con = client.get_connection()?;
Ok(std::thread::spawn(move || loop {
// this is now ok because using con here moves it into the closure
let mut pubsub = con.as_pubsub();
pubsub.subscribe(format!("{}", owned_queue_name)).unwrap();
let msg: String = pubsub.get_message().unwrap().get_payload().unwrap();
println!("{}", msg)
})
}

请注意,我打开了对subscribe调用的结果。最好将函数的结果更改为Result<JoinHandle<Result<(), RedisError>>, RedisError>,以便在线程闭包中使用?

最新更新