我正在尝试从服务器获取 OAuth 令牌,所以我创建了一个名为Token
. 为了在令牌过期时只保留一个请求,我为请求的未来保留了一个参考,让其他请求继续等待它返回。游乐场:
use futures::lock::Mutex; // 0.3.18
use futures_util::{future::Shared, Future, FutureExt}; // 0.3.18
use std::{pin::Pin, sync::Arc};
use tokio::time::Duration; // 1.14.0
pub struct Token {
pub token: String,
pub requesting:
Arc<Mutex<Option<Shared<Pin<Box<dyn Future<Output = Result<String, ()>> + Send>>>>>>,
}
impl Token {
// Get token from server, I hope it does not run repeatly
async fn get_access_token_from_server(&mut self) -> Result<String, ()> {
tokio::time::sleep(Duration::from_secs(10)).await;
self.token = "test".to_owned();
Ok(self.token.clone())
}
//Shows error:`is required to live as long as `'static` here`, why?
pub async fn access_token(&mut self) -> Result<String, ()> {
/*
if !self.token.is_expire() {
return Ok(self.token.clone());
}
*/
let req_arc = self.requesting.clone();
let req_mutex = req_arc.lock().await;
let req = if req_mutex.is_some() {
req_mutex.clone().map(|s| s.clone()).unwrap()
} else {
let req = self.get_access_token_from_server().boxed().shared();
*req_mutex = Some(req.clone());
req
};
req.await
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
/*
Just example, in the real code, the token will keep in another struct with long life
*/
let mut token = Token {
token: String::from(""),
requesting: Arc::new(Mutex::new(None)),
};
let token_string = token.access_token().await;
println!("{:?}", token_string);
Ok(())
}
我对生命周期错误感到困惑:
error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> src/main.rs:21:31
|
21 | pub async fn access_token(&mut self) -> Result<String, ()> {
| ^^^^^^^^^
| |
| this data with an anonymous lifetime `'_`...
| ...is captured here...
...
35 | *req_mutex = Some(req.clone());
| ----------- ...and is required to live as long as `'static` here
我不想保持静止;我希望它的生命周期与结构相同。
- 是解决问题的正常方法吗?
- 如何更正代码?