Lifetime issue passing reference to hyper handler returning future

#1

Hello

I’ve been trying to pass a reference to the server handler in order to avoid cloning the variable twice as shown below:

let listener_service = move || {
        let challenge = Arc::clone(&challenge);
        service_fn(move |req: Request<Body>| {
            handle(req, &challenge)
        })
    };

I’ve included the full example here: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=10ea31450e88a122455006760d7fcdd1

When I instead try to set the lifetime of the variable I get a different error.

Any clues how to solve this?

Thanks

#2

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b948d692885f8644066db1b08b522775

I got rid of the Box because it was unnecessary, and the references to Arc<_>. Don’t take references to Arc, just clone it and pass it along. If you are doing any work with Futures, it is unlikely that the cost of cloning an Arc is going to be a performance hit.

1 Like
#3

Thanks! I was trying to avoid this double cloning. Isn’t it important?

#4

Cloning an Arc doesn’t cost that much, it’s an atomic increment when you clone and an atomic decrement when the clone is dropped.

2 Likes
#5

Could you explain why Box is not needed? I took it off an example that suggested it is good for trait objects.

#6

impl trait syntax is not the same as trait object, you tell the compiler: I will return a type, always the same, and it implements this trait. It’s also a newish syntax maybe it wasn’t available when the exemple was made. You can read more about it here in the book.

1 Like
#7

awesome thanks

#8

Would I still need Box though if handle() has to return more than one Future type (like FutureResult)?

I guess there’s also Either.

#9

If you know all possible types, you can use an Enum. @HadrienG made a comparison between the two in this reply, there are also crates that make the enum for you but I don’t know if they work when it’s not a trait you made.