| IO::Async::Resolver |
IO::Async::Resolver - performing name resolutions asynchronously
This object is used indirectly via an IO::Async::Loop:
use IO::Async::Loop; my $loop = IO::Async::Loop->new();
$loop->resolve( type => 'getpwuid', data => [ $< ], on_resolved => sub { print "My passwd ent: " . join( "|", @_ ) . "\n" },
on_error =>
sub { print "Cannot look up my passwd ent - $_[0]\n" },
);
$loop->loop_forever;
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::DetachedCode 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.
Performs a single name resolution operation, as given by the keys in the hash.
The %params hash keys the following keys:
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.
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.
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.
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.
The IO::Async::DetachedCode object underlying this class uses the
storable argument marshalling type, which means complex data structures
can be passed by reference. Because the resolver will run in a separate
process, the function should make sure to return all of the result in the
returned list; i.e. modifications to call arguments will not be propagated
back to the caller.
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 two resolver names are implemented using the same-named
functions from the Socket::GetAddrInfo module.
getaddrinfo getnameinfo
The getaddrinfo resolver 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. The getnameinfo resolver returns its result unchanged.
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>
| IO::Async::Resolver |