File: flush_cache.rs

package info (click to toggle)
rust-trust-dns-resolver 0.22.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 672 kB
  • sloc: makefile: 2
file content (101 lines) | stat: -rw-r--r-- 3,261 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#![recursion_limit = "128"]

#[cfg(feature = "tokio-runtime")]
fn main() {
    tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap()
        .block_on(async {
            tokio_main().await;
        });
}

#[cfg(feature = "tokio-runtime")]
async fn tokio_main() {
    use trust_dns_resolver::{TokioAsyncResolver, TokioHandle};

    let resolver = {
        // To make this independent, if targeting macOS, BSD, Linux, or Windows, we can use the system's configuration:
        #[cfg(any(unix, windows))]
        {
            // use the system resolver configuration
            TokioAsyncResolver::from_system_conf(TokioHandle)
        }

        // For other operating systems, we can use one of the preconfigured definitions
        #[cfg(not(any(unix, windows)))]
        {
            // Directly reference the config types
            use trust_dns_resolver::config::{ResolverConfig, ResolverOpts};

            // Get a new resolver with the google nameservers as the upstream recursive resolvers
            AsyncResolver::tokio(
                ResolverConfig::quad9(),
                ResolverOpts::default(),
                //runtime.handle().clone(),
            )
        }
    }
    .map(std::sync::Arc::new)
    .expect("failed to create resolver");

    // Create some futures representing name lookups.
    let names = ["trust-dns.org.", "estada.ch.", "wikipedia.org."];

    let first_resolve = resolve_list(&names, &*resolver).await;
    let cached_resolve = resolve_list(&names, &*resolver).await;

    resolver.clear_cache();
    let second_resolve = resolve_list(&names, &*resolver).await;

    println!("first_resolve: {first_resolve:?}");
    println!("cached_resolve: {cached_resolve:?}");
    println!("second_resolve: {second_resolve:?}");

    // Drop the resolver, which means that the runtime will become idle.
    drop(resolver);
}

#[cfg(feature = "tokio-runtime")]
async fn resolve_list<
    C: trust_dns_proto::DnsHandle<Error = trust_dns_resolver::error::ResolveError>,
    P: trust_dns_resolver::ConnectionProvider<Conn = C>,
>(
    names: &[&str],
    resolver: &trust_dns_resolver::AsyncResolver<C, P>,
) -> tokio::time::Duration {
    use tokio::time::Instant;
    let start_time = Instant::now();

    // Create the resolve requests first
    let futures = names
        .iter()
        .map(|name: &&str| {
            let name: String = name.to_string();
            let resolver = resolver.clone();
            let future = {
                let name = name.clone();
                tokio::spawn(async move { resolver.txt_lookup(name).await })
            };
            (name, future)
        })
        .collect::<Vec<_>>();

    // Go through the list of resolution operations in parallel and wait for them to complete.
    for (name, lookup) in futures {
        let txts = lookup.await.expect("unable to spawn resolver").map(|txt| {
            txt.iter()
                .map(|rdata| rdata.to_string())
                .collect::<Vec<_>>()
        });
        println!("  {} returned to {:?}", name, txts);
    }
    println!();
    start_time.elapsed()
}

#[cfg(not(feature = "tokio-runtime"))]
fn main() {
    println!("tokio-runtime feature must be enabled")
}