IO::Async::Resolver - performing name resolutions asynchronously
IO::Async::Resolver
This object is used indirectly via an IO::Async::Loop:
IO::Async::Loop
use IO::Async::Loop; my $loop = IO::Async::Loop->new; $loop->resolver->getaddrinfo( host => "www.example.com", service => "http", on_resolved => sub { foreach my $addr ( @_ ) { printf "http://www.example.com can be reached at " . "socket(%d,%d,%d) + connect('%v02x')\n", @{$addr}{qw( family socktype protocol addr )}; } }, on_error => sub { print "Cannot look up www.example.com - $_[-1]\n"; }, ); $loop->resolve( type => 'getpwuid', data => [ $< ], on_resolved => sub { print "My passwd ent: " . join( "|", @_ ) . "\n"; }, on_error => sub { print "Cannot look up my passwd ent - $_[-1]\n"; }, ); $loop->run;
This module extends an IO::Async::Loop to use the system's name resolver functions asynchronously. It provides a number of named resolvers, each one providing an asynchronous wrapper around a single resolver function.
Because the system may not provide asynchronous versions of its resolver functions, this class is implemented using a IO::Async::Function object that wraps the normal (blocking) functions. In this case, name resolutions will be performed asynchronously from the rest of the program, but will likely be done by a single background worker process, so will be processed in the order they were requested; a single slow lookup will hold up the queue of other requests behind it. To mitigate this, multiple worker processes can be used; see the workers argument to the constructor.
IO::Async::Function
workers
The idle_timeout parameter for the underlying IO::Async::Function object is set to a default of 30 seconds, and min_workers is set to 0. This ensures that there are no spare processes sitting idle during the common case of no outstanding requests.
idle_timeout
min_workers
Performs a single name resolution operation, as given by the keys in the hash.
The %params hash keys the following keys:
%params
Name of the resolution operation to perform. See BUILT-IN RESOLVERS for the list of available operations.
Arguments to pass to the resolver function. Exact meaning depends on the specific function chosen by the type; see BUILT-IN RESOLVERS.
type
Optional. Timeout in seconds, after which the resolver operation will abort with a timeout exception. If not supplied, a default of 10 seconds will apply.
A continuation that is invoked when the resolver function returns a successful result. It will be passed the array returned by the resolver function.
A continuation that is invoked when the resolver function fails. It will be passed the exception thrown by the function.
When returning a future, the on_resolved and on_error continuations are optional.
on_resolved
on_error
A shortcut wrapper around the getaddrinfo resolver, taking its arguments in a more convenient form.
getaddrinfo
The host and service names to look up. At least one must be provided.
Hint values used to filter the results.
Flags to control the getaddrinfo(3) function. See the AI_* constants in Socket's getaddrinfo function for more detail.
getaddrinfo(3)
AI_*
If true, sets the AI_PASSIVE flag. This is provided as a convenience to avoid the caller from having to import the AI_PASSIVE constant from Socket.
AI_PASSIVE
Socket
Time in seconds after which to abort the lookup with a Timed out exception
Timed out
Callback which is invoked after a successful lookup. Will be passed a list of HASH references; each containing one result. Each result will contain fields called family, socktype, protocol and addr. If requested by AI_CANONNAME then the canonname field will also be valid.
family
socktype
protocol
addr
AI_CANONNAME
canonname
$on_resolved->( @addrs )
Callback which is invoked after a failed lookup, including for a timeout.
$on_error->( $exception )
As a specific optimsation, this method will try to perform a lookup of numeric values synchronously, rather than asynchronously, if it looks likely to succeed.
Specifically, if the service name is entirely numeric, and the hostname looks like an IPv4 or IPv6 string, a synchronous lookup will first be performed using the AI_NUMERICHOST flag. If this gives an EAI_NONAME error, then the lookup is performed asynchronously instead.
AI_NUMERICHOST
EAI_NONAME
A shortcut wrapper around the getnameinfo resolver, taking its arguments in a more convenient form.
getnameinfo
The packed socket address to look up.
Flags to control the getnameinfo(3) function. See the NI_* constants in Socket's getnameinfo for more detail.
getnameinfo(3)
NI_*
If true, set the NI_NUMERICHOST, NI_NUMERICSERV or NI_DGRAM flags.
NI_NUMERICHOST
NI_NUMERICSERV
NI_DGRAM
If true, sets both NI_NUMERICHOST and NI_NUMERICSERV flags.
Callback which is invoked after a successful lookup.
$on_resolved->( $host, $service )
As a specific optimsation, this method will try to perform a lookup of numeric values synchronously, rather than asynchronously, if both the NI_NUMERICHOST and NI_NUMERICSERV flags are given.
Registers a new named resolver function that can be called by the resolve method. All named resolvers must be registered before the object is constructed.
resolve
The name of the resolver function; must be a plain string. This name will be used by the type argument to the resolve method, to identify it.
A CODE reference to the resolver function body. It will be called in list context, being passed the list of arguments given in the data argument to the resolve method. The returned list will be passed to the on_resolved callback. If the code throws an exception at call time, it will be passed to the on_error continuation. If it returns normally, the list of values it returns will be passed to on_resolved.
data
The following resolver names are implemented by the same-named perl function, taking and returning a list of values exactly as the perl function does:
getpwnam getpwuid getgrnam getgrgid getservbyname getservbyport gethostbyname gethostbyaddr getnetbyname getnetbyaddr getprotobyname getprotobynumber
The following three resolver names are implemented using the Socket module.
getaddrinfo_hash getaddrinfo_array getnameinfo
The getaddrinfo_hash resolver takes arguments in a hash of name/value pairs and returns a list of hash structures, as the Socket::getaddrinfo function does. For neatness it takes all its arguments as named values; taking the host and service names from arguments called host and service respectively; all the remaining arguments are passed into the hints hash.
getaddrinfo_hash
Socket::getaddrinfo
host
service
The getaddrinfo_array resolver behaves more like the Socket6 version of the function. It takes hints in a flat list, and mangles the result of the function, so that the returned value is more useful to the caller. It splits up the list of 5-tuples into a list of ARRAY refs, where each referenced array contains one of the tuples of 5 values.
getaddrinfo_array
Socket6
As an extra convenience to the caller, both resolvers will also accept plain string names for the family argument, converting inet and possibly inet6 into the appropriate AF_* value, and for the socktype argument, converting stream, dgram or raw into the appropriate SOCK_* value.
inet
inet6
AF_*
stream
dgram
raw
SOCK_*
For backward-compatibility with older code, the resolver name getaddrinfo is currently aliased to getaddrinfo_array; but any code that wishes to rely on the array-like nature of its arguments and return values, should request it specifically by name, as this alias will be changed in a later version of IO::Async.
IO::Async
The getnameinfo resolver returns its result in the same form as Socket.
Because this module simply uses the system's getaddrinfo resolver, it will be fully IPv6-aware if the underlying platform's resolver is. This allows programs to be fully IPv6-capable.
The following somewhat contrieved example shows how to implement a new resolver function. This example just uses in-memory data, but a real function would likely make calls to OS functions to provide an answer. In traditional Unix style, a pair of functions are provided that each look up the entity by either type of key, where both functions return the same type of list. This is purely a convention, and is in no way required or enforced by the IO::Async::Resolver itself.
@numbers = qw( zero one two three four five six seven eight nine ); register_resolver getnumberbyindex => sub { my ( $index ) = @_; die "Bad index $index" unless $index >= 0 and $index < @numbers; return ( $index, $numbers[$index] ); }; register_resolver getnumberbyname => sub { my ( $name ) = @_; foreach my $index ( 0 .. $#numbers ) { return ( $index, $name ) if $numbers[$index] eq $name; } die "Bad name $name"; };
Look into (system-specific) ways of accessing asynchronous resolvers directly
Paul Evans <leonerd@leonerd.org.uk>
To install IO::Async, copy and paste the appropriate command in to your terminal.
cpanm
cpanm IO::Async
CPAN shell
perl -MCPAN -e shell install IO::Async
For more information on module installation, please visit the detailed CPAN module installation guide.