[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