[GH-ISSUE #188] Enable external io_loop in client library lookups #90

Closed
opened 2026-03-07 22:18:43 +03:00 by kerem · 6 comments
Owner

Originally created by @lukaspustina on GitHub (Sep 17, 2017).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/188

Currently, UdpClientConnection::new always creates a new event loop: github.com/bluejekyll/trust-dns@c5ad6c9dd3/client/src/udp/udp_client_connection.rs (L46)
So in case you want to run many lookups, the code creates a lot of tokio_core::reactor::Core instances.

I tries to construct a client manually in order to pass an existing event loop, but the fields of UdpClientConnection are private to this is currently not feasible:

    let name = Name::from_str("example.com.").unwrap();
    let name_server = "8.8.8.8:53".parse().unwrap();
    let (udp_client_stream, client_stream_handle) = UdpClientStream::new(name_server, &io_loop.handle());
    let client_connection = UdpClientConnection{io_loop, udp_client_stream, client_stream_handle};

    let (io_loop, stream, stream_handle) = client_connection.unwrap();

    let client = ClientFuture::new(stream, stream_handle, &io_loop.handle(), None);
    let response = client.query(name, DNSClass::IN, RecordType::A);

    let result = io_loop.run(response).unwrap();
    let answers: &[Record] = result.answers();

    for answer in answers {
        println!(" {:?}", answer);
    }

Is there an other way I haven't found yet to pass an external, already existing event loop to the client or would you consider adding the feature?

Thanks in advance, Lukas

Originally created by @lukaspustina on GitHub (Sep 17, 2017). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/188 Currently, `UdpClientConnection::new` always creates a new event loop: https://github.com/bluejekyll/trust-dns/blob/c5ad6c9dd39f7c5895a65d27780d1c10e6826cc1/client/src/udp/udp_client_connection.rs#L46 So in case you want to run many lookups, the code creates a lot of `tokio_core::reactor::Core` instances. I tries to construct a client manually in order to pass an existing event loop, but the fields of `UdpClientConnection` are private to this is currently not feasible: ``` let name = Name::from_str("example.com.").unwrap(); let name_server = "8.8.8.8:53".parse().unwrap(); let (udp_client_stream, client_stream_handle) = UdpClientStream::new(name_server, &io_loop.handle()); let client_connection = UdpClientConnection{io_loop, udp_client_stream, client_stream_handle}; let (io_loop, stream, stream_handle) = client_connection.unwrap(); let client = ClientFuture::new(stream, stream_handle, &io_loop.handle(), None); let response = client.query(name, DNSClass::IN, RecordType::A); let result = io_loop.run(response).unwrap(); let answers: &[Record] = result.answers(); for answer in answers { println!(" {:?}", answer); } ``` Is there an other way I haven't found yet to pass an external, already existing event loop to the client or would you consider adding the feature? Thanks in advance, Lukas
kerem 2026-03-07 22:18:43 +03:00
Author
Owner

@bluejekyll commented on GitHub (Sep 17, 2017):

Yes. I probably need more docs on this. The UdpClientConnection is designed to work with the SyncClient the corollary for futures is the UdpClientStream. If you want access the tokio semantics, then the ClientFuture type should be used instead. By the way, if all you're doing is lookups, you may want to look at the resolver library, which is designed to do that in the same way as a OS resolver. I have a quick example in the Resolver library for working inside the Tokio framework.

For the client you would follow something similar. The connection types you want would be TCP and UDP. You can use either with the ClientFuture type.

I have some tests that show all of this: https://github.com/bluejekyll/trust-dns/blob/master/integration-tests/tests/client_future_tests.rs#L47

If you don't mind, let me know where more, better documentation is needed. Clearly delineating the difference, and/or renaming the types mentioned here is probably necessary to make this more obvious. Many of these types were named over the evolution of the library, and thus the naming isn't necessarily clear. Clearing all of this up is something that should be done at some point.

<!-- gh-comment-id:330058941 --> @bluejekyll commented on GitHub (Sep 17, 2017): Yes. I probably need more docs on this. The `UdpClientConnection` is designed to work with the `SyncClient` the corollary for futures is the `UdpClientStream`. If you want access the tokio semantics, then the [ClientFuture](https://docs.rs/trust-dns/0.11.3/trust_dns/client/struct.ClientFuture.html) type should be used instead. By the way, if all you're doing is lookups, you may want to look at the resolver library, which is designed to do that in the same way as a OS resolver. I have a quick example in the [Resolver](https://docs.rs/trust-dns-resolver/0.5.0/trust_dns_resolver/#using-the-tokioasync-resolver) library for working inside the Tokio framework. For the client you would follow something similar. The connection types you want would be [TCP](https://docs.rs/trust-dns/0.11.3/trust_dns/tcp/struct.TcpClientStream.html) and [UDP](https://docs.rs/trust-dns/0.11.3/trust_dns/udp/struct.UdpClientStream.html). You can use either with the [ClientFuture](https://docs.rs/trust-dns/0.11.3/trust_dns/client/struct.ClientFuture.html) type. I have some tests that show all of this: https://github.com/bluejekyll/trust-dns/blob/master/integration-tests/tests/client_future_tests.rs#L47 If you don't mind, let me know where more, better documentation is needed. Clearly delineating the difference, and/or renaming the types mentioned here is probably necessary to make this more obvious. Many of these types were named over the evolution of the library, and thus the naming isn't necessarily clear. Clearing all of this up is something that should be done at some point.
Author
Owner

@lukaspustina commented on GitHub (Sep 17, 2017):

Gnarz. Just looked at your text example. It's soo simple. I'll try it during the next few days and will check how the docs may be improved. Thanks so much!

I'll close the ticket once I'm done.

<!-- gh-comment-id:330067056 --> @lukaspustina commented on GitHub (Sep 17, 2017): Gnarz. Just looked at your text example. It's soo simple. I'll try it during the next few days and will check how the docs may be improved. Thanks so much! I'll close the ticket once I'm done.
Author
Owner

@lukaspustina commented on GitHub (Sep 18, 2017):

Perfect. It works. I'll check the docs later.

<!-- gh-comment-id:330308417 --> @lukaspustina commented on GitHub (Sep 18, 2017): Perfect. It works. I'll check the docs later.
Author
Owner

@bluejekyll commented on GitHub (Sep 18, 2017):

You may be interested in some logical changes I'm making to UDP and TCP usage coming in 0.5.1: #189

I'm just finishing up some mock tests for that, will probably release in the next few days.

<!-- gh-comment-id:330309258 --> @bluejekyll commented on GitHub (Sep 18, 2017): You may be interested in some logical changes I'm making to UDP and TCP usage coming in 0.5.1: #189 I'm just finishing up some mock tests for that, will probably release in the next few days.
Author
Owner

@lukaspustina commented on GitHub (Sep 23, 2017):

Frist of all, as my pet project grows, I'm getting more and more into trust-dns as a DNS client and it's wonderful. The library has a great API, the docs are wonderful, and your code is an inspiration on many things. Especially, when I'm stuck with my poor Rust knowledge I turn to your code. Thank you so much for trust-dns.

Regarding the docs, what put me on the wrong track is the lack of an async client example in the docs. I just took a wrong turn and was trapped in the rabbit whole. I think in addition to the SyncClient documentation (https://docs.rs/trust-dns/0.11.3/trust_dns/#querying) there should be an equivalent example for ClientFuture lookups. I'm not sure though that you need to rename the async client into something obvious like AsyncClient. From the futures crate's perspective this name makes sense and I'm afraid AsyncClient wouldn't make munch sense in the context of Futures. For example, it seems unidiomatic to use Future combinators on an object of type AsyncClient.

So, my best guess is to show the trust-dns first time use an async example alongside the sync example.

<!-- gh-comment-id:331643900 --> @lukaspustina commented on GitHub (Sep 23, 2017): Frist of all, as my pet project grows, I'm getting more and more into trust-dns as a DNS client and it's wonderful. The library has a great API, the docs are wonderful, and your code is an inspiration on many things. Especially, when I'm stuck with my poor Rust knowledge I turn to your code. Thank you so much for trust-dns. Regarding the docs, what put me on the wrong track is the lack of an async client example in the docs. I just took a wrong turn and was trapped in the rabbit whole. I think in addition to the `SyncClient` documentation (https://docs.rs/trust-dns/0.11.3/trust_dns/#querying) there should be an equivalent example for `ClientFuture` lookups. I'm not sure though that you need to rename the async client into something obvious like `AsyncClient`. From the futures crate's perspective this name makes sense and I'm afraid `AsyncClient` wouldn't make munch sense in the context of Futures. For example, it seems unidiomatic to use Future combinators on an object of type `AsyncClient`. So, my best guess is to show the trust-dns first time use an async example alongside the sync example.
Author
Owner

@bluejekyll commented on GitHub (Sep 23, 2017):

Thank you for the feedback. And your story is very encouraging, I’m glad this library could be of help.

Thanks for the feedback on the docs. I will add an async example as well to the client library. I’m trying to encourage people to move over to the Resolver for basic needs, but of course for many that’s not all they need.

<!-- gh-comment-id:331644659 --> @bluejekyll commented on GitHub (Sep 23, 2017): Thank you for the feedback. And your story is very encouraging, I’m glad this library could be of help. Thanks for the feedback on the docs. I will add an async example as well to the client library. I’m trying to encourage people to move over to the Resolver for basic needs, but of course for many that’s not all they need.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#90
No description provided.