[Jboss-cvs] JBossAS SVN: r56492 - branches/JBoss_4_0_0_Case10829/naming/src/main/org/jnp/interfaces

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Sep 1 01:02:51 EDT 2006


Author: scott.stark at jboss.org
Date: 2006-09-01 01:02:49 -0400 (Fri, 01 Sep 2006)
New Revision: 56492

Added:
   branches/JBoss_4_0_0_Case10829/naming/src/main/org/jnp/interfaces/NamingContextFactory2.java
Log:
An initial context factory that overrides the default NamingContext with a
TimedLookupContext to run lookups with a timeout across all env servers.

Added: branches/JBoss_4_0_0_Case10829/naming/src/main/org/jnp/interfaces/NamingContextFactory2.java
===================================================================
--- branches/JBoss_4_0_0_Case10829/naming/src/main/org/jnp/interfaces/NamingContextFactory2.java	2006-08-31 22:57:06 UTC (rev 56491)
+++ branches/JBoss_4_0_0_Case10829/naming/src/main/org/jnp/interfaces/NamingContextFactory2.java	2006-09-01 05:02:49 UTC (rev 56492)
@@ -0,0 +1,159 @@
+package org.jnp.interfaces;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.naming.CommunicationException;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+
+import org.jboss.logging.Logger;
+import org.jnp.interfaces.NamingContext;
+
+/**
+ * An initial context factory that overrides the default NamingContext with a
+ * TimedLookupContext.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @version $Revision:$
+ */
+public class NamingContextFactory2 implements InitialContextFactory
+{
+   static Logger log = Logger.getLogger(NamingContextFactory2.class);
+   static final String TIMEOUT_NAME = "jnp.timeout";
+   static ExecutorService lookupPool = Executors.newCachedThreadPool();
+
+   /**
+    * Create a TimedLookupContext that overrides the lookup to execute it in
+    * a thread, retrying if a response it not in in jnp.timeout milliseconds.
+    */
+   public Context getInitialContext(Hashtable env)
+      throws NamingException
+   {
+      String providerURL = (String) env.get(Context.PROVIDER_URL);
+      String[] serverInfo = {};
+      if( providerURL != null )
+      {
+          serverInfo = providerURL.split(",");
+      }
+      return new TimedLookupContext(env, null, serverInfo);
+   }
+
+   /**
+    * Override the NamingContext.lookup method
+    * 
+    * @author Scott.Stark at jboss.org
+    * @version $Revision:$
+    */
+   static class TimedLookupContext extends NamingContext
+   {
+      private static final long serialVersionUID = 1L;
+
+      // Timeout to wait for a connection, 10 seconds is default
+      private int timeout = 10*1000;
+      private ArrayList<String> serverInfo;
+      private boolean trace = log.isTraceEnabled();
+
+      public TimedLookupContext(Hashtable env, Name prefix, String[] servers)
+         throws NamingException
+      {
+         super(env, prefix, null);
+         String to = (String) env.get(TIMEOUT_NAME);
+         this.serverInfo = new ArrayList<String>();
+         this.serverInfo.addAll(Arrays.asList(servers));
+         Collections.shuffle(this.serverInfo);
+         if( to != null )
+         {
+            timeout = Integer.parseInt(to);
+         }
+         if( trace )
+            log.trace("Created TimedLookupContext, timeout: "+timeout+", servers: "+serverInfo);
+      }
+
+      @Override
+      public Object lookup(final Name name) throws NamingException
+      {
+         Object lookup = null;
+         if( trace )
+            log.trace("Begin lookup, name="+name);
+         for(String server : serverInfo)
+         {
+            CallLookup call = new CallLookup(server, name);
+            Future<Object> result = lookupPool.submit(call);
+            try
+            {
+               lookup = result.get(timeout, TimeUnit.MILLISECONDS);
+               return lookup;
+            }
+            catch(TimeoutException t)
+            {
+               if( trace )
+                  log.trace("Lookup timed out for server: "+server);
+            }
+            catch(InterruptedException e)
+            {
+               // Treat as retryable
+               if( trace )
+                  log.trace("Continuing after interrupt", e);
+               continue;
+            }
+            catch(ExecutionException e)
+            {
+               Throwable t = e.getCause();
+               if( trace )
+                  log.trace("Saw exception during lookup, e="+t.getMessage());
+               if( t instanceof CommunicationException )
+               {
+                  if( trace )
+                     log.trace("Continuing after CommunicationException", e);
+                  continue;
+               }
+               else if( t instanceof NamingException )
+                  throw (NamingException) t;
+               else
+               {
+                  NamingException ne = new NamingException("Unexpected failure on lookup of: "+name);
+                  ne.setRootCause(t);
+                  throw ne;
+               }
+            }
+         }
+         if( trace )
+            log.trace("End lookup, name="+name);
+         CommunicationException ce = new CommunicationException("Failed to resolve lookup for servers: "+Arrays.asList(serverInfo));
+         ce.setRemainingName(name);
+         throw ce;
+      }
+
+      class CallLookup implements Callable<Object>
+      {
+         private String serverInfo;
+         private Name name;
+         CallLookup(String serverInfo, Name name)
+         {
+            this.serverInfo = serverInfo;
+            this.name = name;
+         }
+         public Object call() throws Exception
+         {
+            Hashtable callEnv = (Hashtable) env.clone();
+            callEnv.put(Context.PROVIDER_URL, serverInfo);
+            if( trace )
+               log.trace("Performing lookup against: "+serverInfo);
+            NamingContext ctx = new NamingContext(callEnv, null, null);
+            return ctx.lookup(name);
+         }
+      }
+   }
+}




More information about the jboss-cvs-commits mailing list