I have a struct that should be inited once with some value and then it can be freely referenced (or even shared across threads) without problems. The problem is that I want to use it in a handler of hyper
callback. Here is my sample code:
extern crate futures; // 0.1.1
extern crate hyper; // 0.12
use std::net::SocketAddr;
use hyper::service::service_fn;
use hyper::{Body, Request, Response, Server};
use futures::prelude::*;
fn main() {
let token = std::env::args().next().unwrap();
run(&token, "127.0.0.1:8080");
}
fn run(bot_token: &str, listening_address: &str) {
let addr: SocketAddr = listening_address.parse().unwrap();
let server = Server::bind(&addr)
.serve(move || service_fn(|x| echo(x, bot_token)));
}
fn echo(
req: Request<Body>,
bot_token: &str
) -> impl Future<Item = Response<Body>, Error = hyper::Error> + Send {
futures::future::ok(Response::new(Body::empty()))
}
The problem here is that hyper
require callback to be static
:
error[E0621]: explicit lifetime required in the type of `bot_token`
--> src\main.rs:18:10
|
14 | fn run(bot_token: &str, listening_address: &str) {
| --------- consider changing the type of `bot_token` to `&'static str`
...
18 | .serve(move || service_fn(|x| echo(x, bot_token)))
| ^^^^^ lifetime `'static` required
error[E0621]: explicit lifetime required in the type of `bot_token`
--> src\main.rs:19:10
|
14 | fn run(bot_token: &str, listening_address: &str) {
| --------- consider changing the type of `bot_token` to `&'static str`
...
19 | .map_err(|e| eprintln!("server error: {}", e));
| ^^^^^^^ lifetime `'static` required
If I follow this advice and change telegram_client
lifetime to static
I get an error that closure may outlive run
function.
How should I avoid it? I found that I may make it working in following manner:
fn run(bot_token: &str, listening_address: &str) {
let addr: SocketAddr = listening_address.parse().unwrap();
let bot_token = Arc::new(bot_token.to_string());
let server = Server::bind(&addr)
.serve(move || {
let bot_token = bot_token.clone();
service_fn(move |x| echo(x, bot_token.clone()))
});
}
fn echo(
req: Request<Body>,
bot_token: Arc<String>
) -> impl Future<Item = Response<Body>, Error = hyper::Error> + Send {
futures::future::ok(Response::new(Body::empty()))
}
But it looks weird, as well as reference counting for a situation when we know that we won't drop the reference until program exit.