Tomte has asked for the wisdom of the Perl Monks concerning the following question:

In c.l.p.misc someone asked if theres a perl-solution to ask four nameservers in parallel for a certain network-address. After three iterations I had the following code, mostly out of nowhere, that is documentation I once read and now reread and applied to the problem.

Since there was no response in the newsgroup, I ask you to kindly comment on any flaws, cargo-cult, misused idiom and so on you can detect. This is the first time I used fork (besides a fairly standard "deamonizing" fork...); Is the @children array, later used with waitpid(), sensible? Is the locking around the shared-store okay?

I'm humbly waiting for your comments

#!/bin/env perl # # call: # script.pl name.tld # use warnings; use strict; use IPC::ShareLite; use Storable qw(thaw freeze); use File::Temp qw(tempfile); use Fcntl ':flock'; use POSIX ":sys_wait_h"; # allow the child-processes to store their results # so that the parent can access them my $store = new IPC::ShareLite( -key => "__dnssearch__",                 -create  => 'yes',               -destroy => 'no' ) or die "Store: " . $!; my $results = {}; $store->store(freeze($results)); # fake addresses, tested with two real servers my @dnss = qw(111.111.111.111        222.222.222.222        111.222.111.222        222.111.222.111); my $host = $ARGV[0]; my @children = (); # used to "flock" access to the shared storage in the children my $lock = tempfile(); foreach (@dnss) { my $dns = $_; my $parent = fork(); if (!$parent) {         my $command = "nslookup -type=A $host $dns 2>/dev/null";         my $res = qx/$command/;         my $store = new IPC::ShareLite( -key => "__dnssearch__",                             -create  => 'yes',                             -destroy => 'no' ) or warn ("Child $_: ". +$!);         flock($lock, LOCK_EX);         my $results = thaw($store->fetch());         $results->{$dns} = $res;         $store->store(freeze($results));         flock($lock, LOCK_UN);         exit(0); } else {         die "couldn't fork!" unless $parent;         push(@children, $parent); } } # leave no zombies, collect all children # nslookup times out, so there will be an end for (@children) {waitpid($_, 0);} # access results $results = thaw($store->fetch()); # # do something with results # use Data::Dumper; print Data::Dumper->Dump([$results,],["result"]);

Edit: fixed typo in coment.

regards,
tomte


An intellectual is someone whose mind watches itself.
-- Albert Camus

Replies are listed 'Best First'.
Re: Parallel DNS queries (use threads; )
by BrowserUk (Patriarch) on Aug 05, 2004 at 17:10 UTC

    TIMTOWTDI --

    #! perl -slw use strict; use threads qw[ async ]; use Thread::Queue; my @dnss = qw( 111.111.111.111 222.222.222.222 111.222.111.222 222.111.222.111 ); my $Q = new Thread::Queue; my $host = $ARGV[ 0 ]; my $count : shared = @dnss; async{ $Q->enqueue( qx[ nslookup -type=A $host $_ 2>nul ] ); $count--; } for @dnss; sleep 1 while $count; ## Do something with results print $Q->dequeue while $Q->pending;

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
      The semaphores provided with perl's threading modules should provide a nicer solution than sleep 1 while $count.
      -nuffin
      zz zZ Z Z #!perl

        Why write 30 lines of complicated code when one is just about perfect.

        sleep causes the sleeping thread to relinguish its timeslice(s) until the sleep times out, which means almost no load.

        The semaphores api (like the rest of the pthreads api that perls threads are modelled on), is under specified, messy and hard to get right.

        The sleep 1 while $count; is easy to code, easy to understand and "just works" :)


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: Parallel DNS queries -- please comment on code
by integral (Hermit) on Aug 05, 2004 at 16:24 UTC

    There's also POE::Component::Client::DNS which, since it uses POE, doesn't require multiple processes, yet can still resolve in parallel. There's an example in the POE Cookbook called DNS Lookups.

    --
    integral, resident of freenode's #perl
    
Re: Parallel DNS queries -- please comment on code
by lhoward (Vicar) on Aug 05, 2004 at 16:21 UTC
    Net::DNS comes with an example program called mresolv that demonstrate parallel DNS queries.

    L

      Net::DNS comes with an example program called mresolv that demonstrate parallel DNS queries.

      Yes, but multiple queries (different hosts/networks) to the same server, not the same network/host to multiple servers (or did I misread the (kind of sparse!?) documentation)?

      regards,
      tomte


      An intellectual is someone whose mind watches itself.
      -- Albert Camus

        What did you end up using to solve this problem? I want to do the exat same thing - perform simultaneous lookups of a single host to multiple DNS servers