Why does one of these two very similar async Rust functions trigger thread safety errors? - rust

I'm trying something as a learn-Rust project, where I have a library that consumes some REST APIs through a HTTP request trait that I planned to fill in separately for native and webassembly usage, so that I could have bindings for this library in different environments.
My problem arises in the WASM portion, where I'm trying to adapt the fetch example here:
pub async fn run(url: String, authz: String) -> Result<serde_json::Value, JsValue> {
let mut opts = RequestInit::new();
opts.method("GET");
opts.mode(RequestMode::Cors);
let request = Request::new_with_str_and_init(&url, &opts)?;
request.headers().set("Authorization", &authz)?;
let window = web_sys::window().unwrap();
let resp_value = JsFuture::from(window.fetch_with_request(&request)).await?;
assert!(resp_value.is_instance_of::<Response>());
let resp: Response = resp_value.dyn_into().unwrap();
let json = JsFuture::from(resp.json()?).await?;
let parsed: serde_json::Value = json.into_serde().unwrap();
Ok(parsed)
}
I made some light adaptations to suit my purpose here, but it works fine. What doesn't work is my attempt to shoehorn this into the trait interface. The return type is an anyhow::Result, and I unwrap() a bunch of stuff I shouldn't here to temporarily avoid issues with the error type compatibility:
#[async_trait]
impl FetchRequest for WasmFetchRequest {
async fn get(&mut self) -> Result<serde_json::Value> {
let mut opts = RequestInit::new();
opts.method("GET");
opts.mode(RequestMode::Cors);
let request = Request::new_with_str_and_init(&self.path, &opts).unwrap();
request.headers().set("Authorization", &self.authz);
let window = web_sys::window().unwrap();
let resp_value = JsFuture::from(window.fetch_with_request(&request)).await.unwrap();
assert!(resp_value.is_instance_of::<Response>());
let resp: Response = resp_value.dyn_into().unwrap();
let json = JsFuture::from(resp.json().unwrap()).await.unwrap();
let parsed: serde_json::Value = resp.into_serde().unwrap();
Ok(parsed)
/*
// hoped this might work too, same errors
Ok(run(
self.path.to_string(),
self.authz.to_string()
).await.map_err(|err| err.into())?);
*/
}
}
The build is unhappy:
error: future cannot be sent between threads safely
--> src/lib.rs:66:58
|
66 | async fn get(&mut self) -> Result<serde_json::Value> {
| __________________________________________________________^
67 | | /*
68 | | Ok(run(
69 | | self.path.to_string(),
... |
91 | | Ok(parsed)
92 | | }
| |_____^ future created by async block is not `Send`
|
= help: within `impl Future`, the trait `Send` is not implemented for `Rc<RefCell<wasm_bindgen_futures::Inner>>`
note: future is not `Send` as it awaits another future which is not `Send`
--> src/lib.rs:83:26
|
83 | let resp_value = JsFuture::from(window.fetch_with_request(&request)).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `JsFuture`, which is not `Send`
= note: required for the cast to the object type `dyn Future<Output = Result<Value, rescale_core::Error>> + Send`
error: future cannot be sent between threads safely
--> src/lib.rs:66:58
|
66 | async fn get(&mut self) -> Result<serde_json::Value> {
| __________________________________________________________^
67 | | /*
68 | | Ok(run(
69 | | self.path.to_string(),
... |
91 | | Ok(parsed)
92 | | }
| |_____^ future created by async block is not `Send`
|
= help: within `impl Future`, the trait `Send` is not implemented for `*mut u8`
note: future is not `Send` as this value is used across an await
--> src/lib.rs:88:20
|
83 | let resp_value = JsFuture::from(window.fetch_with_request(&request)).await.unwrap();
| ---------- has type `wasm_bindgen::JsValue` which is not `Send`
...
88 | let json = JsFuture::from(resp.json().unwrap()).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `resp_value` maybe used later
...
92 | }
| - `resp_value` is later dropped here
= note: required for the cast to the object type `dyn Future<Output = Result<Value, rescale_core::Error>> + Send`
error: future cannot be sent between threads safely
--> src/lib.rs:66:58
|
66 | async fn get(&mut self) -> Result<serde_json::Value> {
| __________________________________________________________^
67 | | /*
68 | | Ok(run(
69 | | self.path.to_string(),
... |
91 | | Ok(parsed)
92 | | }
| |_____^ future created by async block is not `Send`
|
= help: within `Request`, the trait `Sync` is not implemented for `*mut u8`
note: future is not `Send` as this value is used across an await
--> src/lib.rs:83:26
|
83 | let resp_value = JsFuture::from(window.fetch_with_request(&request)).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ first, await occurs here, with `&request` maybe used later...
note: `&request` is later dropped here
--> src/lib.rs:83:92
|
83 | let resp_value = JsFuture::from(window.fetch_with_request(&request)).await.unwrap();
| -------- ^
| |
| has type `&Request` which is not `Send`
help: consider moving this into a `let` binding to create a shorter lived borrow
--> src/lib.rs:83:41
|
83 | let resp_value = JsFuture::from(window.fetch_with_request(&request)).await.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: required for the cast to the object type `dyn Future<Output = Result<Value, rescale_core::Error>> + Send`
What is the pertinent difference here that causes these errors? I think it must be something with &mut self or else the return type, but I'm out of my depth.
Probably not relevant, but the native counterpart fits into the interface happily enough:
#[async_trait]
impl FetchRequest for NativeFetchRequest {
async fn get(&mut self) -> Result<serde_json::Value> {
let client = reqwest::Client::new();
let mut req = client.get(&self.path);
req = req.header("Authorization", self.authz.as_str());
let res = req.send().await?;
res.error_for_status()?
.json::<serde_json::Value>().await
.map_err(|err| err.into())
}
}

According to async_trait documentation, futures returned by async trait methods must by default be Send:
Async fns get transformed into methods that return Pin<Box<dyn Future + Send + 'async>> and delegate to a private async freestanding function.
Your async fn produced a non-Send future. So the difference between your original code and the one that uses async_trait was that the original code didn't require a Send future, it was okay with non-Send ones, whereas async_trait by default expects Send futures.
To fix the issue, you need to tell async_trait not to require Send using #[async_trait(?Send)] on the trait and the impl block. In other words, replace #[async_trait] with #[async_trait(?Send)] in both the trait declaration and the implementation, and your code should compile. (Playground.)

Related

How to use a Future as yew::callback::Callback

I have following callback which I'm registering to onsubmit event.
use gloo::net::http::Request;
use yew::prelude::*;
let on_submit = Callback::from(async move |ev: FocusEvent| {
ev.prevent_default();
let res = Request::post("https://formsubmit.co/srineshnisala#gmail.com")
.send()
.await
.unwrap();
assert_eq!(res.status(), 200);
});
However, I get following error when I use async
--> src/pages/contact/contact.rs:26:36
|
26 | let on_submit = Callback::from(async move |ev: FocusEvent| {
| _____________________--------------_^
| | |
| | required by a bound introduced by this call
27 | | ev.prevent_default();
28 | |
29 | | let res = Request::post("https://formsubmit.co/srineshnisala#gmail.com")
... |
34 | | assert_eq!(res.status(), 200);
35 | | });
| |_____^ expected `()`, found opaque type
|
::: /home/s1n7ax/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:72:43
|
72 | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
| ------------------------------- the found opaque type
|
= note: expected unit type `()`
found opaque type `impl Future<Output = ()>`
= note: required for `yew::Callback<yew::FocusEvent>` to implement `From<[closure#src/pages/contact/contact.rs:26:36: 26:63]>`
Rust version:
rustc 1.66.0-nightly (01af5040f 2022-10-04)
package versions:
yew = "0.19.3"
yew-router = "0.16.0"
gloo = "0.7.0" # console log and stuff
hyper = "0.14.19" # http requests
How to use an async function as a callback in yew?
You can't create a Callback from an async closure but you can use wasm_bindgen_futures::spawn_local to run a Future on the current thread:
use gloo::net::http::Request;
use yew::prelude::*;
let on_submit = Callback::from(move |ev: FocusEvent| {
ev.prevent_default();
wasm_bindgen_futures::spawn_local(async move {
let res = Request::post("https://formsubmit.co/srineshnisala#gmail.com")
.send()
.await
.unwrap();
assert_eq!(res.status(), 200);
});
});
You can't.
Callback::from(impl Fn(In) -> Out) is the only way to construct a non-noop Callback.
You have to either use block_on to perform an async operation synchronously, or use callback only to register an action in an external async context, for example using a channel.

How to perform actions on a variable in a foreach while being able to use it afterwards

I have the following example code (including use statements too so there's some context on types):
use actix_web::{HttpRequest, HttpResponse, Responder};
use awc::ClientRequest;
pub async fn proxy(req: HttpRequest) -> impl Responder {
let response = construct_request(req).send().await;
let body = response.unwrap().body().await.expect("");
HttpResponse::Ok().body(body)
}
fn construct_request(req: HttpRequest) -> ClientRequest {
let client = awc::Client::default();
let mut new_req = client.get("url");
req.headers().iter().for_each(|headerPair| {
new_req.append_header((headerPair.0, headerPair.1));
});
new_req.content_type("application/json")
}
Currently, the compiler complains that I'm using the new_req value after it being moved in the foreach loop to copy the headers over, which is fair enough, that is what's happening.
error[E0507]: cannot move out of `new_req`, a captured variable in an `FnMut` closure
--> src/routes/proxy.rs:18:9
|
15 | let mut new_req = client.get("http://localhost:8001/ping");
| ----------- captured outer variable
16 |
17 | req.headers().iter().for_each(|headerPair| {
| ___________________________________-
18 | | new_req.append_header((headerPair.0, headerPair.1));
| | ^^^^^^^ ------------------------------------------- `new_req` moved due to this method call
| | |
| | move occurs because `new_req` has type `ClientRequest`, which does not implement the `Copy` trait
19 | | });
| |_____- captured by this `FnMut` closure
|
note: this function takes ownership of the receiver `self`, which moves `new_req`
--> /Users/{sanitized}/awc-3.0.1/src/request.rs:186:30
|
186 | pub fn append_header(mut self, header: impl TryIntoHeaderPair) -> Self {
| ^^^^
warning: variable does not need to be mutable
--> src/routes/proxy.rs:15:9
|
15 | let mut new_req = client.get("http://localhost:8001/ping");
| ----^^^^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
error[E0382]: use of moved value: `new_req`
--> src/routes/proxy.rs:21:5
|
15 | let mut new_req = client.get("http://localhost:8001/ping");
| ----------- move occurs because `new_req` has type `ClientRequest`, which does not implement the `Copy` trait
16 |
17 | req.headers().iter().for_each(|headerPair| {
| ------------ value moved into closure here
18 | new_req.append_header((headerPair.0, headerPair.1));
| ------- variable moved due to use in closure
...
21 | new_req.append_header(("custom", req.headers().get("custom").unwrap()))
| ^^^^^^^ value used here after move
What I can't find out is how I can work around this so that I can continue to use new_req after the foreach loop - is this possible? I've tried doing some googling around preventing this movement but I haven't managed to find anything (I'm assuming this is a very simple resolution that I just don't have the right words to discover)
You'll find by looking at the signature of .append_header() and other methods that they will consume self and return Self. This is a type of builder-pattern that is designed to work like this:
let new_req = client.get("url")
.append_header(...)
.append_header(...)
.append_header(...)
.content_type("application/json");
or like this:
let mut new_req = client.get("url");
new_req = new_req.append_header(...);
new_req = new_req.append_header(...);
new_req = new_req.append_header(...);
new_req = new_req.content_type("application/json");
Unfortunately, constant ownership transfers like this don't play well with closures if you want to keep the value afterwards. You're probably better suited just using a for-loop instead:
for header_pair in req.headers() {
new_req = new_req.append_header(header_pair);
}
Or if you insist on using .for_each(), you can modify the request in-place by using .headers_mut():
req.headers().iter().for_each(|header_pair| {
new_req.headers_mut().insert(header_pair.0.clone(), header_pair.1.clone());
});
If you're in the uncomfortable situation where you must take and reassign ownership and it must be while captured in a closure, you'll have to employ a trick using Option:
// put it in an option
let mut new_req_opt = Some(new_req);
req.headers().iter().for_each(|header_pair| {
// take it out of the option
let mut new_req = new_req_opt.take().unwrap();
// do your thing
new_req = new_req.append_header(header_pair);
// put it back into the option
new_req_opt = Some(new_req);
});
// take it out again at the end
let new_req = new_req_opt.unwrap();

Why can't this actix-web middleware call method not infer that Bytes implements MessageBody?

In the call method of the impl for Service<ServiceRequest>, the B type parameter is bound to 'static + MessageBody and the MessageBody docs say that Bytes implements it, so why does this code:
fn call(&self, req: ServiceRequest) -> Self::Future {
let svc = self.service.clone();
Box::pin(async move {
let sresp = svc.call(req).await.unwrap();
println!("response: {:?}", sresp.headers());
let (hreq, hresp) = sresp.into_parts(); // get request, response
let (hresp, body) = hresp.into_parts(); // get head, body
// to_bytes produces a Bytes, consuming body
let body_bytes = actix_web::body::to_bytes(body)
.await
.map_err(|_| "to_bytes error").unwrap();
println!("Bytes len: {}", body_bytes.len());
// crete new response with original headers and Bytes as body
let new_hresp = hresp.set_body(body_bytes);
// create a nwe ServiceResponse with original request and new response
let new_sresp = ServiceResponse::new(hreq, new_hresp);
Ok(new_sresp)
})
}
produce the error:
expected struct `actix_web::dev::ServiceResponse<B>`
found struct `actix_web::dev::ServiceResponse<actix_web::web::Bytes>`
?
Complete error for reference:
error[E0271]: type mismatch resolving `<impl futures_util::Future<Output = std::result::Result<actix_web::dev::ServiceResponse<actix_web::web::Bytes>, _>> as futures_util::Future>::Output == std::result::Result<actix_web::dev::ServiceResponse<B>, actix_web::Error>`
--> src/main.rs:56:9
|
41 | impl<S, B> Service<ServiceRequest> for LoggingMiddleware<S>
| - this type parameter
...
56 | / Box::pin(async move {
57 | | let sresp = svc.call(req).await.unwrap();
58 | | println!("response: {:?}", sresp.headers());
59 | | let (hreq, hresp) = sresp.into_parts();
... |
65 | | Ok(new_sresp)
66 | | })
| |__________^ expected type parameter `B`, found struct `actix_web::web::Bytes`
|
= note: expected enum `std::result::Result<actix_web::dev::ServiceResponse<B>, actix_web::Error>`
found enum `std::result::Result<actix_web::dev::ServiceResponse<actix_web::web::Bytes>, _>`
= note: required for the cast to the object type `dyn futures_util::Future<Output = std::result::Result<actix_web::dev::ServiceResponse<B>, actix_web::Error>>`
For more information about this error, try `rustc --explain E0271`.
error: could not compile `cryod` due to previous error

Error on Future generator closure: Captured variable cannot escape `FnMut` closure body

I want to create a simple websocket server. I want to process the incoming messages and send a response, but I get an error:
error: captured variable cannot escape `FnMut` closure body
--> src\main.rs:32:27
|
32 | incoming.for_each(|m| async {
| _________________________-_^
| | |
| | inferred to be a `FnMut` closure
33 | | match m {
34 | | // Error here...
35 | | Ok(message) => do_something(message, db, &mut outgoing).await,
36 | | Err(e) => panic!(e)
37 | | }
38 | | }).await;
| |_____^ returns a reference to a captured variable which escapes the closure body
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
This gives a few hits on Stack Overflow but I don't see anywhere in my code where a variable is escaping. The async block won't run concurrently, so I don't see any problem. Furthermore, I feel like I am doing something very simple: I get a type which allows me to send data back to the client, but when using a reference to it in the async block, it gives a compile error. The error only occurs when I use the outgoing or db variable in the async code.
This is my code (error is in the handle_connection function):
main.rs
use tokio::net::{TcpListener, TcpStream};
use std::net::SocketAddr;
use std::sync::Arc;
use futures::{StreamExt, SinkExt};
use tungstenite::Message;
use tokio_tungstenite::WebSocketStream;
struct DatabaseConnection;
#[tokio::main]
async fn main() -> Result<(), ()> {
listen("127.0.0.1:3012", Arc::new(DatabaseConnection)).await
}
async fn listen(address: &str, db: Arc<DatabaseConnection>) -> Result<(), ()> {
let try_socket = TcpListener::bind(address).await;
let mut listener = try_socket.expect("Failed to bind on address");
while let Ok((stream, addr)) = listener.accept().await {
tokio::spawn(handle_connection(stream, addr, db.clone()));
}
Ok(())
}
async fn handle_connection(raw_stream: TcpStream, addr: SocketAddr, db: Arc<DatabaseConnection>) {
let db = &*db;
let ws_stream = tokio_tungstenite::accept_async(raw_stream).await.unwrap();
let (mut outgoing, incoming) = ws_stream.split();
// Adding 'move' does also not work
incoming.for_each(|m| async {
match m {
// Error here...
Ok(message) => do_something(message, db, &mut outgoing).await,
Err(e) => panic!(e)
}
}).await;
}
async fn do_something(message: Message, db: &DatabaseConnection, outgoing: &mut futures_util::stream::SplitSink<WebSocketStream<TcpStream>, Message>) {
// Do something...
// Send some message
let _ = outgoing.send(Message::Text("yay".to_string())).await;
}
Cargo.toml
[dependencies]
futures = "0.3.*"
futures-channel = "0.3.*"
futures-util = "0.3.*"
tokio = { version = "0.2.*", features = [ "full" ] }
tokio-tungstenite = "0.10.*"
tungstenite = "0.10.*"
When using async move, I get the following error:
code
incoming.for_each(|m| async move {
let x = &mut outgoing;
let b = db;
}).await;
error
error[E0507]: cannot move out of `outgoing`, a captured variable in an `FnMut` closure
--> src\main.rs:33:38
|
31 | let (mut outgoing, incoming) = ws_stream.split();
| ------------ captured outer variable
32 |
33 | incoming.for_each(|m| async move {
| ______________________________________^
34 | | let x = &mut outgoing;
| | --------
| | |
| | move occurs because `outgoing` has type `futures_util::stream::stream::split::SplitSink<tokio_tungstenite::WebSocketStream<tokio::net::tcp::stream::TcpStream>, tungstenite::protocol::message::Message>`, which does not implement the `Copy` trait
| | move occurs due to use in generator
35 | | let b = db;
36 | | }).await;
| |_____^ move out of `outgoing` occurs here
FnMut is an anonymous struct, since FnMutcaptured the &mut outgoing, it becomes a field inside of this anonymous struct and this field will be used on each call of FnMut , it can be called multiple times. If you lose it somehow (by returning or moving into another scope etc...) your program will not able to use that field for further calls, due to safety Rust Compiler doesn't let you do this(for your both case).
In your case instead of capturing the &mut outgoing we can use it as argument for each call, with this we'll keep the ownership of outgoing. You can do this by using fold from futures-rs:
incoming
.fold(outgoing, |mut outgoing, m| async move {
match m {
// Error here...
Ok(message) => do_something(message, db, &mut outgoing).await,
Err(e) => panic!(e),
}
outgoing
})
.await;
This may seem a bit tricky but it does the job, we are using constant accumulator(outgoing) which will be used as an argument for our FnMut.
Playground (Thanks #Solomon Ucko for creating reproducible example)
See also :
How to return the captured variable from `FnMut` closure, which is a captor at the same time
How can I move a captured variable into a closure within a closure?

How to reduce lifetime conflicts?

I'm fear about lifetime question. I searched and got so many relative results. I feel so different between of them, and I think it is difficult to get the spirit from them. so I decide to ask.
The error occurred when invoking dao's method inside a Hyper service's call, and I can't fix it!
extern crate futures;
extern crate hyper;
use futures::future::Future;
use futures::Stream;
use hyper::server::{Http, Request, Response, Service};
use hyper::StatusCode;
use std::net::SocketAddr;
trait Dao {
fn input_data(&self, data: &str) -> bool;
}
struct MysqlDao;
impl Dao for MysqlDao {
fn input_data(&self, data: &str) -> bool {
unimplemented!()
}
}
struct HelloWorld<'a> {
dao: &'a Dao,
}
impl<'a> Service for HelloWorld<'a> {
type Request = Request;
type Response = Response;
type Error = hyper::Error;
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
fn call(&self, req: Request) -> Self::Future {
Box::new(req.body().concat2().map(|b| {
let rtn = self.dao.input_data(std::str::from_utf8(b.as_ref()).unwrap());
let rtn = true; // line 35 this is ok
match rtn {
true => {
return Response::new()
.with_status(StatusCode::Ok)
.with_body(String::from("ok"));
}
false => {
return Response::new()
.with_status(StatusCode::UnprocessableEntity)
.with_body(String::from("error"));
}
}
}))
}
}
fn main() {
let addr = "127.0.0.1:3000".parse().unwrap();
static DAO: MysqlDao = MysqlDao;
web_startup(&addr, &DAO);
}
fn web_startup<T: Dao>(addr: &SocketAddr, dao: &'static T) {
let server = Http::new()
.bind(addr, move || Ok(HelloWorld { dao }))
.unwrap();
server.run().unwrap();
}
playground
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:33:9
|
33 | / Box::new(req.body().concat2().map(|b| {
34 | | let rtn = self.dao.input_data(std::str::from_utf8(b.as_ref()).unwrap());
35 | | let rtn = true; // line 35 this is ok
36 | | match rtn {
... |
47 | | }
48 | | }))
| |___________^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 26:1...
--> src/main.rs:26:1
|
26 | / impl<'a> Service for HelloWorld<'a> {
27 | | type Request = Request;
28 | | type Response = Response;
29 | | type Error = hyper::Error;
... |
49 | | }
50 | | }
| |_^
note: ...so that the type `futures::Map<futures::stream::Concat2<hyper::Body>, [closure#src/main.rs:33:43: 48:10 self:&&HelloWorld<'a>]>` will meet its required lifetime bounds
--> src/main.rs:33:9
|
33 | / Box::new(req.body().concat2().map(|b| {
34 | | let rtn = self.dao.input_data(std::str::from_utf8(b.as_ref()).unwrap());
35 | | let rtn = true; // line 35 this is ok
36 | | match rtn {
... |
47 | | }
48 | | }))
| |___________^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that expression is assignable (expected std::boxed::Box<futures::Future<Error=hyper::Error, Item=hyper::Response> + 'static>, found std::boxed::Box<futures::Future<Error=hyper::Error, Item=hyper::Response>>)
--> src/main.rs:33:9
|
33 | / Box::new(req.body().concat2().map(|b| {
34 | | let rtn = self.dao.input_data(std::str::from_utf8(b.as_ref()).unwrap());
35 | | let rtn = true; // line 35 this is ok
36 | | match rtn {
... |
47 | | }
48 | | }))
| |___________^
The problem line is 34. When I replace line 34 with line 35, it works.
There's a couple of things going on with lifetimes in this code, and the error message is not that great.
The first thing is that your call function returns a trait object; that is, Box<T> where T is a trait instead of a concrete type. The default lifetime for a trait object is 'static, so Box<Future> is equivalent to Box<Future + 'static>. That explains where this line of the message comes from:
note: ...so that expression is assignable (expected std::boxed::Box<futures::Future<Error=hyper::Error, Item=hyper::Response> + 'static>, found std::boxed::Box<futures::Future<Error=hyper::Error, Item=hyper::Response>>)
In this case, you don't need your returned Future to have the 'static lifetime. Instead, you want it to have the same lifetime as self.dao, so change your type alias as follows:
type Future = Box<'a + Future<Item = Self::Response, Error = Self::Error>>;
The second thing is what variables your closure captures. Your closure refers to self, so it needs to save away that reference. This means the closure can't live past the end of the method - but you've already specified it will live as long as 'a; that is, it will live at least as long as self.dao.
Note that self in this method does not have the lifetime 'a. The instance of HelloWorld might have a shorter lifetime than the dao it has a reference to.
To fix this half of the problem, you need to allow the closure to capture only self.dao without capturing self. So you have to add
let dao = self.dao;
before the closure, and then refer to dao instead of self.dao inside the closure, so that it won't capture self. You also need to make the closure a move closure, otherwise it ends up capturing a reference to the reference, which still ties the lifetime to the scope of the function.
User red75prime, who originally posted this suggestion in a comment, made a playground with these changes. Lines 30, 33, and 34 are the important ones.
I found a way, but I think it's ugly.
Remove dao property from HelloWorld; add Sync to trait Dao; move out DAO to upper scope; invoke DAO directly from fn call.
Code : playground

Resources