一个奇怪的问题,如果 get_vec param config 从外部传递,test_get_vec current_thread::block_on_all 将永远不会结束并执行 println。但是如果我在 get_vec 中重新初始化配置参数,current_thread::block_on_all 将得到结果和 println。 我使用 reqwest = { version = "0.9.24" }, tokio = "0.1", futures = "0.1"
use std::collections::HashMap;
use std::mem;
use std::str::FromStr;
use std::time::{Duration, Instant};
use block_modes::cipher::errors;
use error_chain::error_chain;
use futures::{Future, Stream};
use hyper::header::HeaderValue;
use hyper::http::response;
use reqwest::{Error, get, Url};
use reqwest::r#async::{Client, Decoder};
use reqwest::r#async::Client as HttpClient;
use reqwest::r#async::ClientBuilder;
use reqwest::r#async::RequestBuilder;
use serde::de::DeserializeOwned;
use serde_derive::{Deserialize, Serialize};
use tokio::runtime::current_thread;
use crate::test::QueryOptions;
#[derive(Clone, Debug)]
pub struct Config {
pub address: String,
pub datacenter: Option<String>,
pub http_client: HttpClient,
pub token: Option<String>,
pub wait_time: Option<Duration>,
}
#[derive(Clone, Default, Eq, PartialEq, Serialize, Deserialize, Debug)]
pub struct KVPair {
pub Key: String,
}
pub type ConsulGetVecFuture<R> = Box<dyn Future<Item=Result<(R), String>, Error=Error>>;
pub fn get_vec<R: DeserializeOwned + Default + 'static>(
path: &str,
config: &Config,
mut params: HashMap<String, String>,
) -> Result<ConsulGetVecFuture<R>, String> {
let url_str = format!("{}{}", config.address, path);
let url = Url::parse_with_params(&url_str, params.iter()).unwrap();
/* if uncomment this block, it works, no more block
let config = ClientBuilder::new()
.build()
.map(|client| Config {
address: String::from("http://consul.test.com".to_string()),
datacenter: None,
http_client: client,
token: None,
wait_time: None,
}).unwrap();
*/
let request_builder = config.http_client.get(url);
let response = request_builder.send();
let fu = response.and_then(|mut r| {
r.into_body().concat2()
})
.and_then(|body| {
println!("body: {:?}", body);
Ok(body)
})
.map(move |body| {
let j: R = serde_json::from_slice::<R>(&body).unwrap_or_else(|e| {
println!("Failed to parse response: {}", e);
R::default()
});
Ok(j)
}).map_err(|err| {
err
});
Ok(Box::new(fu))
}
#[test]
fn test_get_vec() {
let mut params = HashMap::new();
params.insert(String::from("recurse"), String::from(""));
let path = "/xxx/infra-java-server";
let config = ClientBuilder::new()
.build()
.map(|client| Config {
address: String::from("http://consul.test.com".to_string()),
datacenter: None,
http_client: client,
token: None,
wait_time: None,
}).unwrap();
let kv = get_vec::<KVPair>(path, &config, params).unwrap();
let kv = current_thread::block_on_all(kv).unwrap().unwrap();
println!("==================ends================")
}