[GH-ISSUE #698] [Client] Recommended stable version? #275

Closed
opened 2026-03-07 23:11:07 +03:00 by kerem · 6 comments
Owner

Originally created by @alienscience on GitHub (Mar 3, 2019).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/698

After a cargo update trust dns client updated from 0.15.0 to 0.15.1. This brought in some breaking changes to the API (in UdpClientStream::new()). From what I can see, this API changes again in 0.16.X.

Is there a recommended version to aim at for stability?

Also, I had problems searching the source code for 0.15.1 because, as far as I can tell, this release is not tagged in git.

The code that I have that is sensitive to trust dns versions is:

// Connect to the given dns server asynchronously
fn connect_client<A>(
    dns_addr: A,
) -> (
    impl Future<Item = (), Error = ()>,
    BasicClientHandle<DnsMultiplexerSerialResponse>,
)
where
    A: ToSocketAddrs,
{
    let mut addrs = dns_addr.to_socket_addrs().unwrap();
    let sock_addr = addrs.next().unwrap();
    let (stream, handle) = UdpClientStream::new(sock_addr);
    ClientFuture::new(stream, handle, None)
}

Do you have any advice for refactoring the function or return types so that it is less likely to break?

Many thanks for the library and thanks in advance for any help.

Originally created by @alienscience on GitHub (Mar 3, 2019). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/698 After a `cargo update` trust dns client updated from `0.15.0` to `0.15.1`. This brought in some breaking changes to the API (in `UdpClientStream::new()`). From what I can see, this API changes again in `0.16.X`. Is there a recommended version to aim at for stability? Also, I had problems searching the source code for `0.15.1` because, as far as I can tell, this release is not tagged in git. The code that I have that is sensitive to trust dns versions is: ```rust // Connect to the given dns server asynchronously fn connect_client<A>( dns_addr: A, ) -> ( impl Future<Item = (), Error = ()>, BasicClientHandle<DnsMultiplexerSerialResponse>, ) where A: ToSocketAddrs, { let mut addrs = dns_addr.to_socket_addrs().unwrap(); let sock_addr = addrs.next().unwrap(); let (stream, handle) = UdpClientStream::new(sock_addr); ClientFuture::new(stream, handle, None) } ``` Do you have any advice for refactoring the function or return types so that it is less likely to break? Many thanks for the library and thanks in advance for any help.
kerem 2026-03-07 23:11:07 +03:00
Author
Owner

@bluejekyll commented on GitHub (Mar 3, 2019):

That's unfortunate that there was an API breakage on that version. It wasn't intentional. There was a UDP socket leak in 0.15.0 that 0.15.1 fixed, and fixing that may have introduced this breaking API change.

The 0.15.x line is stable. For alpha releases, I don't guarantee that there won't be breaking changes during their development. Apologies for the API change breaking you!

In 0.16 I'm starting to try and clean up a lot of things that I haven't had time to address in a while, so that might be an upgrade, though I do try to deprecate interfaces before changing them in a breaking way, I can't always guarantee this.

<!-- gh-comment-id:469036398 --> @bluejekyll commented on GitHub (Mar 3, 2019): That's unfortunate that there was an API breakage on that version. It wasn't intentional. There was a UDP socket leak in 0.15.0 that 0.15.1 fixed, and fixing that may have introduced this breaking API change. The 0.15.x line is stable. For alpha releases, I don't guarantee that there won't be breaking changes during their development. Apologies for the API change breaking you! In 0.16 I'm starting to try and clean up a lot of things that I haven't had time to address in a while, so that might be an upgrade, though I do try to deprecate interfaces before changing them in a breaking way, I can't always guarantee this.
Author
Owner

@alienscience commented on GitHub (Mar 3, 2019):

Thanks for the reply. I will upgrade to 0.15.1.

<!-- gh-comment-id:469059321 --> @alienscience commented on GitHub (Mar 3, 2019): Thanks for the reply. I will upgrade to 0.15.1.
Author
Owner

@clouds56 commented on GitHub (Mar 12, 2019):

I don't care about DnsMultiplexerSerialResponse or UdpResponse when using a BasicClientHandle, why I have to specify it?
Is it possible to box something like ClientHandle in order to use in a struct?

<!-- gh-comment-id:472136280 --> @clouds56 commented on GitHub (Mar 12, 2019): I don't care about DnsMultiplexerSerialResponse or UdpResponse when using a BasicClientHandle, why I have to specify it? Is it possible to box something like ClientHandle in order to use in a struct?
Author
Owner

@bluejekyll commented on GitHub (Mar 12, 2019):

The Client hasn't gotten a ton of love in the past while. It's been low on my priorities after the server and resolver, but I have wanted to cleanup and simplify it's interfaces. If you don't absolutely need the Async aspects of the client, can you instead use the synchronous client? https://docs.rs/trust-dns/0.16.0-alpha.2/trust_dns/client/struct.SyncClient.html

I'm not sure if all the types in the AsyncClient are object-safe, so it might not be easy to wrap them.

<!-- gh-comment-id:472160688 --> @bluejekyll commented on GitHub (Mar 12, 2019): The Client hasn't gotten a ton of love in the past while. It's been low on my priorities after the server and resolver, but I have wanted to cleanup and simplify it's interfaces. If you don't absolutely need the Async aspects of the client, can you instead use the synchronous client? https://docs.rs/trust-dns/0.16.0-alpha.2/trust_dns/client/struct.SyncClient.html I'm not sure if all the types in the AsyncClient are object-safe, so it might not be easy to wrap them.
Author
Owner

@clouds56 commented on GitHub (Mar 13, 2019):

Thanks for the information.
I take some time investigated the struct SyncClient, but it also need a parameter CC. The trait trust_dns::client::Client won't work as well.
In my situation, I'd like to make dns a field of my Client struct

struct Client {
  ...
  dns: ??; // what's here? expect something like Arc/Box<dyn trust_dns::client::Client>
}

I would not like to make my struct generic just for dns, from my situation, I expect dns/Client to have the trait (no need to know if the underlying Client is tcp/udp, secure or not)

trait Client {
  fn query(
        &self,
        name: &Name,
        query_class: DNSClass,
        query_type: RecordType,
    ) -> ClientResult<DnsResponse>; // and that's all
  // other interfaces like notify<R>, create<R> could also appear here
  // and all are independent from Response, Sender, SenderFuture, Handle
}

could we separate fn new_future(&self) (along with Response, Sender, SenderFuture, Handle) to another trait (say InnerClient) and make trait Client takes no arguments?

impl<F,S,R> Client for InnerClient<Response=R, Sender=S, SenderFuture=F, Handle=BasicClientHandle<R>>
<!-- gh-comment-id:472294325 --> @clouds56 commented on GitHub (Mar 13, 2019): Thanks for the information. I take some time investigated the struct `SyncClient`, but it also need a parameter `CC`. The trait `trust_dns::client::Client` won't work as well. In my situation, I'd like to make dns a field of my Client struct ```rust struct Client { ... dns: ??; // what's here? expect something like Arc/Box<dyn trust_dns::client::Client> } ``` I would not like to make my struct generic just for dns, from my situation, I expect dns/Client to have the trait (no need to know if the underlying Client is tcp/udp, secure or not) ```rust trait Client { fn query( &self, name: &Name, query_class: DNSClass, query_type: RecordType, ) -> ClientResult<DnsResponse>; // and that's all // other interfaces like notify<R>, create<R> could also appear here // and all are independent from Response, Sender, SenderFuture, Handle } ``` could we separate `fn new_future(&self)` (along with `Response, Sender, SenderFuture, Handle`) to another trait (say `InnerClient`) and make trait `Client` takes no arguments? ```rust impl<F,S,R> Client for InnerClient<Response=R, Sender=S, SenderFuture=F, Handle=BasicClientHandle<R>> ```
Author
Owner

@bluejekyll commented on GitHub (Mar 13, 2019):

could we separate fn new_future(&self) (along with Response, Sender, SenderFuture, Handle) to another trait (say InnerClient) and make trait Client takes no arguments?

Yes, that might work. At that point I think the Client trait would be object safe. If you want to take a stab at that change, I'd welcome the PR.

<!-- gh-comment-id:472295339 --> @bluejekyll commented on GitHub (Mar 13, 2019): > could we separate fn new_future(&self) (along with Response, Sender, SenderFuture, Handle) to another trait (say InnerClient) and make trait Client takes no arguments? Yes, that might work. At that point I think the Client trait would be object safe. If you want to take a stab at that change, I'd welcome the PR.
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#275
No description provided.