[jboss-cvs] JBossAS SVN: r84348 - in projects/ejb3/trunk/async-impl: src/main/java/org/jboss/ejb3/async/impl and 8 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Feb 17 23:51:36 EST 2009


Author: ALRubinger
Date: 2009-02-17 23:51:36 -0500 (Tue, 17 Feb 2009)
New Revision: 84348

Added:
   projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/
   projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/
   projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/ResultUnwrappingFuture.java
   projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/ResultUnwrappingThreadPoolExecutor.java
   projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/PausableProcessingAsyncContainer.java
   projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/AsyncTestUtil.java
Removed:
   projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/future/
   projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/hack/DevelopmentHacks.java
   projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/AsyncFutureWrapper.java
   projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/PausableProcessingAsyncContainer.java
Modified:
   projects/ejb3/trunk/async-impl/pom.xml
   projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/interceptor/AsynchronousInterceptor.java
   projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/PausableBlockingQueue.java
   projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/unit/CancelAsyncTaskTestCase.java
   projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/ThreadPoolAsyncContainer.java
   projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/simple/unit/SimpleAsyncTestCase.java
Log:
[EJBTHREE-1721] EJB 3.1 @Asynchronous Future.cancel(), Future.isCancelled(), Future.isDone() support

Modified: projects/ejb3/trunk/async-impl/pom.xml
===================================================================
--- projects/ejb3/trunk/async-impl/pom.xml	2009-02-18 04:48:33 UTC (rev 84347)
+++ projects/ejb3/trunk/async-impl/pom.xml	2009-02-18 04:51:36 UTC (rev 84348)
@@ -66,6 +66,10 @@
         <configuration>
           <forkMode>once</forkMode>
           <jvm>${JDK6_HOME}/bin/java</jvm>
+          <!--  
+          Useful in debugging blocking/deadlock/etc
+          <redirectTestOutputToFile>false</redirectTestOutputToFile>  
+          -->
         </configuration>
       </plugin>
       

Deleted: projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/hack/DevelopmentHacks.java
===================================================================
--- projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/hack/DevelopmentHacks.java	2009-02-18 04:48:33 UTC (rev 84347)
+++ projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/hack/DevelopmentHacks.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -1,71 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
-  *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.async.impl.hack;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * DevelopmentHacks
- * 
- * A hack access class used solely in development.  Provides
- * tight coupling between components which will later be bound
- * together as configurable beans via MC
- *
- * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
- * @version $Revision: $
- */
-//TODO Move everything out of here as noted in comments
- at Deprecated
-public final class DevelopmentHacks
-{
-
-   // --------------------------------------------------------------------------------||
-   // Constructor --------------------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   /**
-    * Non-instanciable
-    */
-   private DevelopmentHacks()
-   {
-
-   }
-
-   // --------------------------------------------------------------------------------||
-   // Utilities ----------------------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   /**
-    * Obtains the default ExecutorService to be used for asynchronous
-    * invocations.  Will eventually be injected via MC, as a per-container
-    * configurable property
-    * 
-    * @return 
-    */
-   @Deprecated
-   public static ExecutorService getDefaultAsyncExecutorService()
-   {
-      return Executors.newCachedThreadPool();
-   }
-
-}

Modified: projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/interceptor/AsynchronousInterceptor.java
===================================================================
--- projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/interceptor/AsynchronousInterceptor.java	2009-02-18 04:48:33 UTC (rev 84347)
+++ projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/interceptor/AsynchronousInterceptor.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -31,7 +31,6 @@
 import org.jboss.aop.advice.Interceptor;
 import org.jboss.aop.joinpoint.Invocation;
 import org.jboss.aop.joinpoint.MethodInvocation;
-import org.jboss.ejb3.async.impl.future.AsyncFutureWrapper;
 import org.jboss.ejb3.async.spi.container.AsyncInvocationProcessor;
 import org.jboss.ejb3.interceptors.container.ManagedObjectAdvisor;
 import org.jboss.logging.Logger;
@@ -83,7 +82,7 @@
    /* (non-Javadoc)
     * @see org.jboss.aop.advice.Interceptor#invoke(org.jboss.aop.joinpoint.Invocation)
     */
-   public Object invoke(Invocation invocation) throws Throwable
+   public Object invoke(final Invocation invocation) throws Throwable
    {
       // If asynchronous
       if (this.isAsyncInvocation(invocation))
@@ -108,28 +107,29 @@
     * a queue for asynchronous processing, returning 
     * a handle to the task
     */
-   private Future<?> invokeAsync(Invocation invocation)
+   private Future<?> invokeAsync(final Invocation invocation)
    {
       // Get the target container
-      AsyncInvocationProcessor container = this.getInvocationProcessor(invocation);
+      final AsyncInvocationProcessor container = this.getInvocationProcessor(invocation);
 
       // Get the ExecutorService
-      ExecutorService executorService = container.getAsynchronousExecutor();
+      final ExecutorService executorService = container.getAsynchronousExecutor();
 
       // Get the existing SecurityContext
-      SecurityContext sc = SecurityActions.getSecurityContext();
+      final SecurityContext sc = SecurityActions.getSecurityContext();
 
+      // Copy the invocation (must be done for Thread safety, as we spawn this off and 
+      // subsequent calls can mess with the internal interceptor index
+      final Invocation nextInvocation = invocation.copy();
+
       // Make the asynchronous task from the invocation
-      Callable<Object> asyncTask = new AsyncInvocationTask<Object>(invocation.copy(), sc);
+      final Callable<Object> asyncTask = new AsyncInvocationTask<Object>(nextInvocation, sc);
 
       // Short-circuit the invocation into new Thread 
-      Future<Object> task = executorService.submit(asyncTask);
+      final Future<Object> task = executorService.submit(asyncTask);
 
-      // Make a Future handle for the caller
-      Future<Object> handle = new AsyncFutureWrapper(task);
-
       // Return
-      return handle;
+      return task;
    }
 
    /**
@@ -138,15 +138,15 @@
     * 
     * EJB 3.1 4.5.2.2
     */
-   private boolean isAsyncInvocation(Invocation invocation)
+   private boolean isAsyncInvocation(final Invocation invocation)
    {
       // Precondition check
       assert invocation instanceof MethodInvocation : this.getClass().getName() + " supports only "
             + MethodInvocation.class.getSimpleName() + ", but has been passed: " + invocation;
-      MethodInvocation si = (MethodInvocation) invocation;
+      final MethodInvocation si = (MethodInvocation) invocation;
 
       // Get the actual method
-      Method actualMethod = si.getActualMethod();
+      final Method actualMethod = si.getActualMethod();
 
       // Determine if asynchronous (either returns Future or has @Asynchronous)
       if (invocation.resolveAnnotation(Asynchronous.class) != null || actualMethod.getReturnType().equals(Future.class))
@@ -181,8 +181,10 @@
     * 
     * @return
     */
-   private AsyncInvocationProcessor getInvocationProcessor(Invocation invocation)
+   private AsyncInvocationProcessor getInvocationProcessor(final Invocation invocation)
    {
+      //TODO This won't work when we integrate w/ ejb3-core, as Advisor will need:
+      // ((ManagedObjectAdvisor) invocation.getAdvisor()).getContainer().getEJBContainer();
       return (AsyncInvocationProcessor) ((ManagedObjectAdvisor) invocation.getAdvisor()).getContainer();
    }
 
@@ -196,14 +198,14 @@
     */
    private class AsyncInvocationTask<V> implements Callable<V>
    {
-      private Invocation invocation;
+      private final Invocation invocation;
 
       /**
        * SecurityContext to use for the invocation
        */
-      private SecurityContext sc;
+      private final SecurityContext sc;
 
-      public AsyncInvocationTask(Invocation invocation, SecurityContext sc)
+      public AsyncInvocationTask(final Invocation invocation, final SecurityContext sc)
       {
          this.invocation = invocation;
          this.sc = sc;
@@ -213,7 +215,7 @@
       public V call() throws Exception
       {
          // Get existing security context
-         SecurityContext oldSc = SecurityActions.getSecurityContext();
+         final SecurityContext oldSc = SecurityActions.getSecurityContext();
 
          try
          {

Copied: projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent (from rev 84250, projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/future)

Deleted: projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/AsyncFutureWrapper.java
===================================================================
--- projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/future/AsyncFutureWrapper.java	2009-02-16 14:11:42 UTC (rev 84250)
+++ projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/AsyncFutureWrapper.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -1,147 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
-  *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.async.impl.future;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.jboss.logging.Logger;
-
-/**
- * AsyncFutureWrapper
- * 
- * Client view of an EJB 3.1 Asynchronous invocation's return
- * value
- *
- * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
- * @version $Revision: $
- */
-public class AsyncFutureWrapper<V> implements Future<V>
-{
-   // --------------------------------------------------------------------------------||
-   // Class Members ------------------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   private static final long serialVersionUID = 1L;
-
-   private static final Logger log = Logger.getLogger(AsyncFutureWrapper.class);
-
-   // --------------------------------------------------------------------------------||
-   // Instance Members ---------------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   /**
-    * Underlying target for inquiry
-    */
-   private Future<Future<V>> target;
-
-   // --------------------------------------------------------------------------------||
-   // Constructor --------------------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   /**
-    * Constructs a new AsyncFuture for the given invocation
-    * 
-    * @param target The Future returned by the executor
-    */
-   public AsyncFutureWrapper(final Future<Future<V>> target)
-   {
-      // Set properties
-      this.setTarget(target);
-   }
-
-   // --------------------------------------------------------------------------------||
-   // Required Implementations -------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   public boolean cancel(boolean mayInterruptIfRunning)
-   {
-      return this.getUnderlyingTarget().cancel(mayInterruptIfRunning);
-   }
-
-   /**
-    * Obtains the 
-    */
-   public V get() throws InterruptedException, ExecutionException
-   {
-      // Get the underlying target
-      Future<V> underlyingTarget = this.getUnderlyingTarget();
-
-      // Invoke (ignore a null value as this indicates no return/void)
-      V returnValue = underlyingTarget == null ? null : underlyingTarget.get();
-
-      // Return
-      return returnValue;
-   }
-
-   public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
-   {
-      Future<V> underlyingTarget = this.getUnderlyingTarget();
-      return underlyingTarget == null ? null : underlyingTarget.get(timeout, unit);
-   }
-
-   public boolean isCancelled()
-   {
-      return this.getUnderlyingTarget().isCancelled();
-   }
-
-   public boolean isDone()
-   {
-      return this.getUnderlyingTarget().isDone();
-   }
-
-   // --------------------------------------------------------------------------------||
-   // Accessors / Mutators -----------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   private void setTarget(Future<Future<V>> target)
-   {
-      // Precondition checks
-      assert target != null : "target must be specified";
-
-      // Set
-      this.target = target;
-   }
-
-   // --------------------------------------------------------------------------------||
-   // Internal Helper Methods --------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   private Future<V> getUnderlyingTarget()
-   {
-      try
-      {
-         return target.get();
-      }
-      catch (InterruptedException e)
-      {
-         throw new RuntimeException(e);
-      }
-      catch (ExecutionException e)
-      {
-         throw new RuntimeException(e);
-      }
-   }
-
-}

Copied: projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/ResultUnwrappingFuture.java (from rev 84250, projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/future/AsyncFutureWrapper.java)
===================================================================
--- projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/ResultUnwrappingFuture.java	                        (rev 0)
+++ projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/ResultUnwrappingFuture.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -0,0 +1,154 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.async.impl.util.concurrent;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.ejb.AsyncResult;
+
+import org.jboss.logging.Logger;
+
+/**
+ * ResultUnwrappingFuture
+ * 
+ * Client view of an EJB 3.1 Asynchronous invocation's return
+ * value 
+ * 
+ * <br /><br />
+ * 
+ * Required to unwrap the javax.ejb.AsyncResult<V> that has been given as a
+ * return value by the bean provider
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ResultUnwrappingFuture<V> extends FutureTask<V> implements Future<V>
+{
+   // --------------------------------------------------------------------------------||
+   // Class Members ------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   private static final long serialVersionUID = 1L;
+
+   private static final Logger log = Logger.getLogger(ResultUnwrappingFuture.class);
+
+   // --------------------------------------------------------------------------------||
+   // Constructor --------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /*
+    * Delegate constructors back up to the super implementation
+    */
+
+   public ResultUnwrappingFuture(Callable<V> callable)
+   {
+      super(callable);
+   }
+
+   public ResultUnwrappingFuture(Runnable runnable, V result)
+   {
+      super(runnable, result);
+   }
+
+   // --------------------------------------------------------------------------------||
+   // Required Implementations -------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /*
+    * (non-Javadoc)
+    * @see java.util.concurrent.Future#get()
+    */
+   public V get() throws InterruptedException, ExecutionException
+   {
+      // Log
+      if (log.isTraceEnabled())
+      {
+         log.trace("Blocking request to get()");
+      }
+
+      // Get the result specified by the bean provider
+      final Object returnValueFromBeanProvider = super.get();
+      V wrappedValue = this.getWrappedFuture(returnValueFromBeanProvider);
+
+      // Return
+      return wrappedValue;
+   }
+
+   /*
+    * (non-Javadoc)
+    * @see java.util.concurrent.Future#get(long, java.util.concurrent.TimeUnit)
+    */
+   public V get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException,
+         TimeoutException
+   {
+      // Log
+      if (log.isTraceEnabled())
+      {
+         log.trace("Request to get() with timeout " + timeout + " (" + unit + ")");
+      }
+
+      // Get the result specified by the bean provider
+      final Object returnValueFromBeanProvider = super.get(timeout, unit);
+      V wrappedValue = this.getWrappedFuture(returnValueFromBeanProvider);
+
+      // Return
+      return wrappedValue;
+   }
+
+   // --------------------------------------------------------------------------------||
+   // Internal Helper Methods --------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /**
+    * Unwraps the AsyncFuture result given by the bean provider
+    * and returns the real return value
+    */
+   @SuppressWarnings("unchecked")
+   private V getWrappedFuture(final Object returnValueFromBeanProvider) throws InterruptedException, ExecutionException
+   {
+      // Allow nulls to pass through (return type of void)
+      if (returnValueFromBeanProvider == null)
+      {
+         return null;
+      }
+
+      // Ensure it's in expected form
+      if (!(returnValueFromBeanProvider instanceof AsyncResult))
+      {
+         throw new RuntimeException("Bean provider has not specified a return value of type "
+               + AsyncResult.class.getName() + ", was instead: " + returnValueFromBeanProvider);
+      }
+
+      // Get the underlying result
+      final AsyncResult<V> result = (AsyncResult<V>) returnValueFromBeanProvider;
+      final V unwrappedReturnValue = result.get(); // Not blocking, as AsyncResult is not a blocking implementation
+
+      // Return
+      return unwrappedReturnValue;
+   }
+
+}


Property changes on: projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/ResultUnwrappingFuture.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Added: projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/ResultUnwrappingThreadPoolExecutor.java
===================================================================
--- projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/ResultUnwrappingThreadPoolExecutor.java	                        (rev 0)
+++ projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/util/concurrent/ResultUnwrappingThreadPoolExecutor.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -0,0 +1,96 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.async.impl.util.concurrent;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * ResultUnwrappingThreadPoolExecutor
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class ResultUnwrappingThreadPoolExecutor extends ThreadPoolExecutor
+{
+
+   // --------------------------------------------------------------------------------||
+   // Constructor --------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /**
+    * Delegates to super implementation only
+    */
+   public ResultUnwrappingThreadPoolExecutor(int corePoolSize, int maxPoolSize, long keepAliveTime, TimeUnit unit,
+         BlockingQueue<Runnable> workQueue)
+   {
+      super(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue);
+   }
+
+   // --------------------------------------------------------------------------------||
+   // Overridden Implementations -----------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /*
+    * The "submit" methods below effectively perform the same
+    * function as those specified by AbstractExecutorService, 
+    * though we'll use our own j.u.c.Future implementation 
+    * in order to unwrap an AsyncResult return type given by the
+    * bean provider
+    */
+
+   @Override
+   public <T> Future<T> submit(Callable<T> task)
+   {
+      if (task == null)
+         throw new NullPointerException();
+      FutureTask<T> ftask = new ResultUnwrappingFuture<T>(task);
+      execute(ftask);
+      return ftask;
+   }
+
+   @Override
+   public <T> Future<T> submit(Runnable task, T result)
+   {
+      if (task == null)
+         throw new NullPointerException();
+      FutureTask<T> ftask = new ResultUnwrappingFuture<T>(task, result);
+      execute(ftask);
+      return ftask;
+   }
+
+   @Override
+   public Future<?> submit(Runnable task)
+   {
+      if (task == null)
+         throw new NullPointerException();
+      FutureTask<Object> ftask = new ResultUnwrappingFuture<Object>(task, null);
+      execute(ftask);
+      return ftask;
+   }
+
+}

Modified: projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/PausableBlockingQueue.java
===================================================================
--- projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/PausableBlockingQueue.java	2009-02-18 04:48:33 UTC (rev 84347)
+++ projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/PausableBlockingQueue.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -32,19 +32,17 @@
 
 /**
  * PausableBlockingQueue
+ * 
+ * Does not comply with contracts provided by j.u.c.BlockingQueue.  For
+ * testing only.
+ * 
+ * This implementation supports "pausing" a work queue such that no new tasks 
+ * will be submitted while inactive.  Upon reactivation the backlog of tasks 
+ * will be added to the queue.
  *
  * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
  * @version $Revision: $
  */
- at Deprecated
-//TODO 
-/*
- * This implementation doesn't work with j.u.c out of the box
- * because we're "pausing" at the wrong level.  Calls to Future.get(time,unit)
- * block indefinitely because the task is never submitted while in pause mode.
- * 
- * Meaning we have to get at the work queue through some other mechanism, not through here
- */
 public class PausableBlockingQueue<E> implements BlockingQueue<E>
 {
    // --------------------------------------------------------------------------------||
@@ -68,8 +66,9 @@
     * Access must be synchronized with itself
     */
    /*
-    * volatile because only one Thread may set this (pause/unpause),
-    * the main Thread from the test 
+    * volatile because we don't want to synchronize access 
+    * here for queue operations "offer" and "take", but we
+    * need the Thread visibility to be correct
     */
    private volatile BlockingQueue<E> currentQueue;
 

Copied: projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/PausableProcessingAsyncContainer.java (from rev 84280, projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/PausableProcessingAsyncContainer.java)
===================================================================
--- projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/PausableProcessingAsyncContainer.java	                        (rev 0)
+++ projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/PausableProcessingAsyncContainer.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.async.impl.test.cancel;
+
+import java.util.concurrent.TimeUnit;
+
+import org.jboss.ejb3.async.impl.test.common.ThreadPoolAsyncContainer;
+import org.jboss.ejb3.async.impl.util.concurrent.ResultUnwrappingThreadPoolExecutor;
+import org.jboss.ejb3.async.spi.container.AsyncInvocationProcessor;
+
+/**
+ * PausableProcessingAsyncContainer
+ * 
+ * A Container which permits blocking upon the work queue to pause processing
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class PausableProcessingAsyncContainer<T> extends ThreadPoolAsyncContainer<T>
+      implements
+         AsyncInvocationProcessor
+{
+
+   // --------------------------------------------------------------------------------||
+   // Constructors -------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   public PausableProcessingAsyncContainer(String name, String domainName, Class<? extends T> beanClass)
+   {
+      super(name, domainName, beanClass, new ResultUnwrappingThreadPoolExecutor(3, 6, 3, TimeUnit.SECONDS,
+            new PausableBlockingQueue<Runnable>(false)));
+   }
+
+}


Property changes on: projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/PausableProcessingAsyncContainer.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Modified: projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/unit/CancelAsyncTaskTestCase.java
===================================================================
--- projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/unit/CancelAsyncTaskTestCase.java	2009-02-18 04:48:33 UTC (rev 84347)
+++ projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/cancel/unit/CancelAsyncTaskTestCase.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -22,12 +22,13 @@
 package org.jboss.ejb3.async.impl.test.cancel.unit;
 
 import java.util.concurrent.Future;
+import java.util.concurrent.ThreadPoolExecutor;
 
 import junit.framework.TestCase;
 
 import org.jboss.aspects.common.AOPDeployer;
 import org.jboss.ejb3.async.impl.test.cancel.PausableBlockingQueue;
-import org.jboss.ejb3.async.impl.test.common.PausableProcessingAsyncContainer;
+import org.jboss.ejb3.async.impl.test.cancel.PausableProcessingAsyncContainer;
 import org.jboss.ejb3.async.impl.test.common.Pojo;
 import org.jboss.ejb3.async.impl.test.common.TestConstants;
 import org.jboss.ejb3.async.impl.test.simple.unit.SimpleAsyncTestCase;
@@ -77,22 +78,12 @@
    // Tests --------------------------------------------------------------------------||
    // --------------------------------------------------------------------------------||
 
-   /*
-    * In place just so Maven doesn't puke on no valid tests
-    */
-   @Test
-   @Deprecated
-   //TODO Remove
-   public void noopTest()
-   {
-   }
-
    /**
     * Tests that @Asynchronous invocations may be cancelled
     * 
     * @throws Throwable 
     */
-   //@Test
+   @Test
    @SuppressWarnings("unchecked")
    public void testCancelAsyncInvocation() throws Throwable
    {
@@ -100,7 +91,9 @@
       BeanContext<Pojo> bean = container.construct();
 
       // Set the container to allow processing
-      PausableBlockingQueue<?> queue = (PausableBlockingQueue<?>) container.getAsynchronousExecutor().getQueue();
+      //TODO Relying on impls?
+      ThreadPoolExecutor executor = (ThreadPoolExecutor) container.getAsynchronousExecutor();
+      PausableBlockingQueue<?> queue = (PausableBlockingQueue<?>) executor.getQueue();
       queue.resume();
       log.info("Work queue is active");
 
@@ -135,14 +128,25 @@
 
       // Cancel and test
       boolean isCancelled = secondIncrementCounterFuture.cancel(true);
-      TestCase.assertTrue("Request to cancel() not honored", isCancelled);
+      TestCase.assertTrue("Request to cancel() reporting not honored", isCancelled);
+      log.info("Request to cancel reports as honored");
 
+      // Ensure the cancelled task reports as done
+      boolean isDone = secondIncrementCounterFuture.isDone();
+      TestCase.assertTrue("Cancelled task did not report as done", isDone);
+      log.info("Request to cancel reports as done");
+
+      // Resume the work queue
+      queue.resume();
+      log.info("Work queue is active again");
+
       // Get the counter again, testing that it hasn't been incremented
       Future<Integer> secondIncrementCounterResultFuture = (Future<Integer>) container.invoke(bean,
             TestConstants.METHOD_NAME_GET_COUNTER);
       int secondIncrementCounterResult = secondIncrementCounterResultFuture.get();
       TestCase.assertEquals("Second call to increment counter should have been cancelled", firstIncrementCounterResult,
             secondIncrementCounterResult);
+      log.info("Second call to increment counter was cancelled, counter = " + secondIncrementCounterResult);
 
    }
 

Copied: projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/AsyncTestUtil.java (from rev 84250, projects/ejb3/trunk/async-impl/src/main/java/org/jboss/ejb3/async/impl/hack/DevelopmentHacks.java)
===================================================================
--- projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/AsyncTestUtil.java	                        (rev 0)
+++ projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/AsyncTestUtil.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.async.impl.test.common;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.jboss.ejb3.async.impl.util.concurrent.ResultUnwrappingThreadPoolExecutor;
+
+/**
+ * AsyncTestUtil
+ * 
+ * A utility class used solely in tests.  Provides
+ * tight coupling between components which will typically be
+ * together as configurable beans via MC
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public final class AsyncTestUtil
+{
+
+   // --------------------------------------------------------------------------------||
+   // Constructor --------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /**
+    * Non-instanciable
+    */
+   private AsyncTestUtil()
+   {
+
+   }
+
+   // --------------------------------------------------------------------------------||
+   // Utilities ----------------------------------------------------------------------||
+   // --------------------------------------------------------------------------------||
+
+   /**
+    * Obtains the default ExecutorService to be used for asynchronous
+    * invocations.  In reality, this is injected via MC, as a per-container
+    * configurable property
+    * 
+    * @return 
+    */
+   public static ExecutorService getDefaultAsyncExecutorService()
+   {
+      return new ResultUnwrappingThreadPoolExecutor(3, 6, 3L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
+   }
+
+}


Property changes on: projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/AsyncTestUtil.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Deleted: projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/PausableProcessingAsyncContainer.java
===================================================================
--- projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/PausableProcessingAsyncContainer.java	2009-02-18 04:48:33 UTC (rev 84347)
+++ projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/PausableProcessingAsyncContainer.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -1,79 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
-  *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.async.impl.test.common;
-
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import org.jboss.ejb3.async.impl.test.cancel.PausableBlockingQueue;
-import org.jboss.ejb3.async.spi.container.AsyncInvocationProcessor;
-
-/**
- * PausableProcessingAsyncContainer
- * 
- * A Container which permits blocking upon the work queue to pause processing
- *
- * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
- * @version $Revision: $
- */
-public class PausableProcessingAsyncContainer<T> extends ThreadPoolAsyncContainer<T>
-      implements
-         AsyncInvocationProcessor
-{
-   // --------------------------------------------------------------------------------||
-   // Instance Members ---------------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   /**
-    * To be used for asynchronous invocations
-    */
-   private ThreadPoolExecutor asynchronousExecutor;
-
-   // --------------------------------------------------------------------------------||
-   // Constructors -------------------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   public PausableProcessingAsyncContainer(String name, String domainName, Class<? extends T> beanClass)
-   {
-      super(name, domainName, beanClass, new ThreadPoolExecutor(3, 6, 3, TimeUnit.SECONDS,
-            new PausableBlockingQueue<Runnable>(false)));
-   }
-
-   // --------------------------------------------------------------------------------||
-   // Required Implementations -------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   public ThreadPoolExecutor getAsynchronousExecutor()
-   {
-      return asynchronousExecutor;
-   }
-
-   // --------------------------------------------------------------------------------||
-   // Accessors / Mutators -----------------------------------------------------------||
-   // --------------------------------------------------------------------------------||
-
-   public void setAsynchronousExecutor(ThreadPoolExecutor asynchronousExecutor)
-   {
-      this.asynchronousExecutor = asynchronousExecutor;
-   }
-
-}

Modified: projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/ThreadPoolAsyncContainer.java
===================================================================
--- projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/ThreadPoolAsyncContainer.java	2009-02-18 04:48:33 UTC (rev 84347)
+++ projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/common/ThreadPoolAsyncContainer.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -23,7 +23,6 @@
 
 import java.util.concurrent.ExecutorService;
 
-import org.jboss.ejb3.async.impl.hack.DevelopmentHacks;
 import org.jboss.ejb3.async.spi.container.AsyncInvocationProcessor;
 import org.jboss.ejb3.interceptors.direct.DirectContainer;
 
@@ -50,7 +49,7 @@
 
    public ThreadPoolAsyncContainer(String name, String domainName, Class<? extends T> beanClass)
    {
-      this(name, domainName, beanClass, DevelopmentHacks.getDefaultAsyncExecutorService());
+      this(name, domainName, beanClass, AsyncTestUtil.getDefaultAsyncExecutorService());
    }
 
    public ThreadPoolAsyncContainer(String name, String domainName, Class<? extends T> beanClass,

Modified: projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/simple/unit/SimpleAsyncTestCase.java
===================================================================
--- projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/simple/unit/SimpleAsyncTestCase.java	2009-02-18 04:48:33 UTC (rev 84347)
+++ projects/ejb3/trunk/async-impl/src/test/java/org/jboss/ejb3/async/impl/test/simple/unit/SimpleAsyncTestCase.java	2009-02-18 04:51:36 UTC (rev 84348)
@@ -101,6 +101,14 @@
 
       // Ensure the value is expected
       TestCase.assertEquals("Did not obtain expected result", Pojo.VALUE, result);
+
+      // Ensure the result reports as done
+      boolean isDone = futureResult.isDone();
+      TestCase.assertTrue("Completed task did not report as done", isDone);
+
+      // Ensure the result does not report as cancelled
+      boolean isCancelled = futureResult.isCancelled();
+      TestCase.assertFalse("Completed task reported as cancelled", isCancelled);
    }
 
    /**




More information about the jboss-cvs-commits mailing list