Browse the docs

silk.net.resolver_native.

The native provider of the Resolver effect, with the getaddrinfo function of the system.

When to use#

Provide NativeSystemResolver for Resolver in a native program when a blocking lookup is acceptable. Code that resolves uses silk.net.resolver, so a test can provide a fake.

Details#

A host name without a deadline makes one getaddrinfo call with the name as written, so names in the hosts file, such as localhost, resolve. The result is copied, and the list of the system is freed one time, also on errors. Numeric hosts do not call the provider.

Errors#

ResolverError if the host is not found, has no address of the selected family, or the lookup fails. A host name with a deadline fails with DeadlineUnsupported.

Gotchas#

  • A host name with a deadline fails with DeadlineUnsupported before the lookup. After getaddrinfo starts, it cannot be cancelled or limited in time or memory.

  • The lookup blocks the thread. It does not let another fiber run.

  • NativeSystemResolver.make fails to compile on targets other than Darwin on aarch64, and Linux with GNU libc on x86_64 or aarch64.

Examples#

Use the system resolver#

silk
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.core.effect { Effect }
import silk.system.monotonic_clock { MonotonicClock }
import silk.net.resolver_native { NativeSystemResolver }
import silk.net.address { AddressError, Host, Port }
import silk.core.option { Option }
import silk.system.monotonic_clock_native { OsMonotonicClock }
import silk.core.result { Result }
import silk.net.resolver { FamilySelection, ResolveRequest, ResolvedEndpoints, Resolver, ResolverError }
import silk.system.system_clock { Instant, SystemClock }

fn request(name: string, deadline: Option<Instant>) -> Option<ResolveRequest> {
  let host = match Host.parse(name) {
    Result<Host, AddressError>.Success { value } => value
    Result<Host, AddressError>.Failure { error: _ } => {
      return Option<ResolveRequest>.none()
    }
  }
  return match ResolveRequest.make(host, Port.fromU16(443), FamilySelection.Any, 8, move deadline) {
    Result<ResolveRequest, ResolverError>.Success { value } => Option<ResolveRequest>.some(
      move value
    )
    Result<ResolveRequest, ResolverError>.Failure { error: _ } => Option<ResolveRequest>.none()
  }
}

// Returns the number of endpoints of `name`. It blocks until the system lookup ends.
effect fn countEndpoints(name: string) -> usize
  ! ResolverError | OutOfMemoryError
  ? &mut Resolver | &mut MonotonicClock | &mut Allocator {
  let lookup = match request(name, Option<Instant>.none()) {
    Option.Some { value } => move value
    Option.None => {
      return 0
    }
  }
  let endpoints = run Resolver.resolve(&lookup)
  return ResolvedEndpoints.length(&endpoints)
}

pub fn main() -> i32 {
  let mut allocator = Allocator.systemAllocatorProvider()
  let mut resolver = NativeSystemResolver.make()
  let mut clock = OsMonotonicClock.make()

  // A host name with a deadline fails before the lookup starts.
  let limited = match request("example.com", Option<Instant>.some(SystemClock.make(1, 0))) {
    Option.Some { value } => move value
    Option.None => {
      return 1
    }
  }
  let attempted = run Effect.result(Resolver.resolve(&limited))
    |> Effect.provideMut<Resolver>(&mut resolver)
    |> Effect.provideMut<MonotonicClock>(&mut clock)
    |> Effect.provideMut<Allocator>(&mut allocator)
  return match move attempted {
    Result.Success { value: _ } => 1
    Result.Failure { error } => match move error {
      ResolverError.DeadlineUnsupported => 0
      _ => 1
    }
  }
}

Import as NativeSystemResolver with import silk.net.resolver_native { NativeSystemResolver }.

Public declarations: 1.

NativeSystemResolver#

silk
pub struct NativeSystemResolver

The native Resolver provider, with the getaddrinfo function of the system. It has no state.

When to use#

Provide it for Resolver in a native program when a blocking lookup is acceptable. Code that resolves uses silk.net.resolver, so a test can provide a fake.

Details#

A host name without a deadline makes one getaddrinfo call with the name as written, so names in the hosts file, such as localhost, resolve. The result is copied, and the list of the system is freed one time, also on errors. Numeric hosts do not call the provider.

Gotchas#

  • A host name with a deadline fails with DeadlineUnsupported before the lookup. After getaddrinfo starts, it cannot be cancelled or limited in time or memory.

  • The lookup blocks the thread. It does not let another fiber run.

Implementation NativeSystemResolver#

silk
impl NativeSystemResolver

Associated function make#

silk
pub fn make() -> NativeSystemResolver

Returns a resolver. It does no lookup.

Gotchas#

It fails to compile on targets other than Darwin on aarch64, and Linux with GNU libc on x86_64 or aarch64.

Implementation Resolver for NativeSystemResolver#

silk
impl Resolver for NativeSystemResolver

Operation resolveDomain#

silk
resolveDomain: NativeSystemResolver.resolveDomain

Category: Networking.

Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.

View the source of this page