I have a service which updates cache data on a fixed interval. Every N seconds it will trigger a future using a loop (tokio::run(future_update(http_client.clone()))
), but it is not returned to the parent function where the future resolved. The loop blocks and I get only one iteration.
When I create a new hyper HTTP client instead of passing a cloned one then everything works correctly. It's does not working Arc<Client>
either.
pub fn trigger_cache_reload(http_client: Arc<Client<HttpConnector, Body>>) {
let load_interval_sec = get_load_interval_sec(conf.load_interval_seconds.clone());
std::thread::spawn(move || loop {
let http_client = http_client.clone();
info!("Woke up");
tokio::run(pipeline(http_client));
info!(
"Pipeline run complete. Huuhh Now I need sleep of {} secs. Sleeping",
load_interval_sec
);
std::thread::sleep(std::time::Duration::from_secs(load_interval_sec));
});
}
fn pipeline(
client: Arc<Client<HttpConnector, Body>>,
) -> Box<dyn Future<Item = (), Error = ()> + Send> {
let res = fetch_message_payload() //return type of this call is Box<dyn Future<Item = (), Error = Error> + Send>
.map_err(Error::from)
.and_then(|_| {
//let client = hyper::Client::builder().max_idle_per_host(1).build_http();
//if i create new client here every time and use it then all working is fine.
refresh_cache(client) //return type of this call is Box<dyn Future<Item = (), Error = Error> + Send>
.map_err(Error::from)
.and_then(|arg| {
debug!("refresh_cache completed");
Ok(arg)
})
});
let res = res.or_else(|e| {
error!("error {:?}", e);
Ok(())
});
Box::new(res)
}
After calling of trigger_cache_reload
once, I get the "woke up"
log message. I also get "refresh_cache completed"
log message after some time on successful completion of future. I do not get the "sleeping"
log message with or without Arc
.
If I create a new client inside the future every time, I am able to get "sleeping"
log messages.