Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FuturesResolver need to be kept around for at least the lifetime of the Future #4

Closed
azdlowry opened this issue Nov 9, 2017 · 3 comments

Comments

@azdlowry
Copy link

azdlowry commented Nov 9, 2017

I'm not sure if this is actually an issue or my misunderstanding of the intention. Modifying the futures.rs example with the following main function:

fn main() {
    // Create Resolver and make a query.
    let query = {
        let resolver = FutureResolver::new().expect("Failed to create resolver");
        resolver.query_mx("gmail.com").then(|result| {
            print_mx_results(&result);
            result
        })
    };

    // Run the query to completion and print the results.
    let mut event_loop = tokio_core::reactor::Core::new().expect("Failed to create event loop");
    event_loop.run(query).ok();
}

This will always fail because FutureResolver is dropped before the the query is executed on the reactor.

The examples work fine, however in practise DNS lookup is just the first step of a larger operation and it can be difficult to code such that the FutureResolver is kept around long enough. It may be possible to put it in a lazy static, I'm not certain what is the affect of keeping the FutureResolver around for ever. (Especially in circumstances where the network might change)

@dimbleby
Copy link
Owner

dimbleby commented Nov 9, 2017

This is as designed, but I understand that it's not entirely intuitive and perhaps even unhelpful.

I think I see a way to keep things alive while queries are pending, but I must admit that I'm in two minds about whether this is always the desired behaviour - I've become accustomed to things as they are!

Probably the code that you want to write above is completely reasonable, but it might take me a little while to reflect and convince myself of that; and then also a little while to implement it...

@azdlowry
Copy link
Author

azdlowry commented Nov 9, 2017

I usually write Futures so that the they consume everything it needs to complete, then the future itself controls the lifetime. This is how I've worked around the issue, by wrapping the Future returned from resolver.query_a in another Future that consumes the FutureResolver.

@dimbleby
Copy link
Owner

dimbleby commented Nov 9, 2017

Sure, my proposed mechanism is somewhat similar. I've pushed a sketch of the idea here, where the trickiness is happening in query_mx() (and would have to be repeated in all the other places).

But I want to think about this for a bit before committing to it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants