[concurrency-interest] Migrating DNS problem to j.u.c

robert lazarski robertlazarski at gmail.com
Tue Dec 12 16:06:31 EST 2006


On 12/12/06, Tim Peierls <tim at peierls.net> wrote:
> The minimal approach

Thanks for the reply Tim. I've decided to start from scratch as the
original code is broke in several ways. The whole recursion part may
be a misunderstanding of the original coder. Anyways, while I'm trying
to figure it out I implemented it using j.u.c and I'm posting it here
in case someone could review it.

There is one question I have: awaitTermination doesn't do what I
expect - end after 100 seconds, ie, I get the List returned but the
main() keeps going. Perhaps something to do with daemon threads. Any
insight appreciated.

package org;

import static java.lang.System.out;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;

public class DNS
{

  public static void main(String[] args) throws Exception {
      helloDNS();
  }

  /*******************************************************************
  Use this method to test dns
  *******************************************************************/
  private static void helloDNS() throws Exception {
       calculateDNS("bee.uspnet.usp.br", "usp.br");
  }

  private static List<String> calculateDNS(String dnsIP, String domain)
          throws Exception {

      Hashtable<String, String> env = new Hashtable<String, String>();
      env.put("java.naming.factory.initial",
"com.sun.jndi.dns.DnsContextFactory");
      env.put("java.naming.provider.url",  "dns://" + dnsIP + "/");

      // obter contexto inicial
      DirContext ictx = null;
      NamingEnumeration hostEnumeration = null;
      try {
          out.println("getting conn: ");
          ictx = new InitialDirContext(env);
          out.println("getting conn, getting list ");
          hostEnumeration = ictx.list(domain);
          out.println("got list ");
      } catch (Exception ex) {
          ex.printStackTrace();
          throw new Exception(ex);
      }
      ExecutorService exec = Executors.newCachedThreadPool(
              new ONExceptionThreadFactory(new ONExceptionHandler()));
      // skip those already found
      Queue <String> domainsVisitedQueue = new ConcurrentLinkedQueue<String>();
      domainsVisitedQueue.add(domain);
      Queue <String> resultQueue = new ConcurrentLinkedQueue<String>();
      parallelRecursiveDNS(exec, ictx, hostEnumeration,
domainsVisitedQueue, resultQueue);
      exec.awaitTermination(100L, TimeUnit.SECONDS);

      return new ArrayList<String>(resultQueue);
  }	

  private static void parallelRecursiveDNS(final Executor exec, final
DirContext ictx,
          final NamingEnumeration hostEnumeration, final
Collection<String> domainsVisitedQueue,
          final Collection<String> results)
      throws Exception {

      while (hostEnumeration.hasMore()) {

          exec.execute(new Runnable() {
              public void run() {
                  try {
                      String host = null;
                      host = ((NameClassPair) hostEnumeration.next())
                              .getNameInNamespace();
                      results.add(host);
                      out.println("Found host: " + host);
                      // all 'A records'
                      Attributes a = ictx.getAttributes(host,
                              new String[] { "A" });
                      if (a.get("A") != null) {
                          String ip = a.get("A").get().toString();
                          results.add(ip);
                          out.println("Found ip: " + ip);
                      }
                      // enter task suitable for recursion?
                      Attributes aDNS = ictx.getAttributes(host,
                                  new String[] { "NS" });
                      NamingEnumeration allDNS = aDNS.getAll();
                      while (allDNS.hasMore()) {
                          out.println("Entering allDNS: ");
                          Attribute attr = (Attribute) allDNS.next();
                          NamingEnumeration values = attr.getAll();
                          String dns = values.next().toString();
                          if (domainsVisitedQueue.contains(dns)) {
                              continue;
                          }
                          NamingEnumeration newHost = ictx.list(dns);
                          out.println("doing recursion: ");
                          parallelRecursiveDNS(exec, ictx, newHost,
domainsVisitedQueue, results);
                      }
                  } catch (Exception ex) { ex.printStackTrace(); }

              }

          });
      }
  }
}


More information about the Concurrency-interest mailing list