Author: hlship
Date: Wed Apr  8 21:17:16 2009
New Revision: 763398

URL: http://svn.apache.org/viewvc?rev=763398&view=rev
Log:
TAP5-634: Google App Engine Support: ability to disable code that creates new 
threads

Added:
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutor.java
   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/parallel.apt   (with 
props)
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutorTest.java
   (with props)
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelModule.java
   (with props)
Modified:
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/IOCSymbols.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ParallelExecutor.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/advice.apt
    tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/IOCSymbols.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/IOCSymbols.java?rev=763398&r1=763397&r2=763398&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/IOCSymbols.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/IOCSymbols.java
 Wed Apr  8 21:17:16 2009
@@ -36,4 +36,13 @@
      * Default is one minute (an epoch in application time).
      */
     public static final String THREAD_POOL_KEEP_ALIVE = 
"tapestry.thread-pool.keep-alive";
+
+    /**
+     * By default, the {...@link 
org.apache.tapestry5.ioc.services.ParallelExecutor} service uses a thread pool. 
In
+     * environments (such as Google Application Engine) where thread creation 
is not allowed, this can be set to
+     * "false", and deferred logic will, instead, execute immediately.
+     *
+     * @since 5.1.0.3
+     */
+    public static final String THREAD_POOL_ENABLED = 
"tapestry.thread-pool-enabled";
 }

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutor.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutor.java?rev=763398&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutor.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutor.java
 Wed Apr  8 21:17:16 2009
@@ -0,0 +1,70 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc.internal.services;
+
+import org.apache.tapestry5.ioc.Invokable;
+import org.apache.tapestry5.ioc.services.ParallelExecutor;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Implementation of {...@link ParallelExecutor} used when {...@linkplain 
org.apache.tapestry5.IOCSymbols#THREAD_POOL_ENABLED
+ * the thread pool is disabled}.
+ *
+ * @since 5.1.0.3
+ */
+public class NonParallelExecutor implements ParallelExecutor
+{
+    public <T> Future<T> invoke(Invokable<T> invocable)
+    {
+        final T result = invocable.invoke();
+
+        return new Future<T>()
+        {
+            public boolean cancel(boolean mayInterruptIfRunning)
+            {
+                return false;
+            }
+
+            public boolean isCancelled()
+            {
+                return false;
+            }
+
+            public boolean isDone()
+            {
+                return true;
+            }
+
+            public T get() throws InterruptedException, ExecutionException
+            {
+                return result;
+            }
+
+            public T get(long timeout, TimeUnit unit) throws 
InterruptedException, ExecutionException, TimeoutException
+            {
+                return result;
+            }
+        };
+    }
+
+    public <T> T invoke(Class<T> proxyType, Invokable<T> invocable)
+    {
+        return invocable.invoke();
+    }
+}

Propchange: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ParallelExecutor.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ParallelExecutor.java?rev=763398&r1=763397&r2=763398&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ParallelExecutor.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ParallelExecutor.java
 Wed Apr  8 21:17:16 2009
@@ -22,6 +22,7 @@
  * A service that allows work to occur in parallel using a thread pool. The 
thread pool is started lazily, and is
  * shutdown when the Registry is shutdown.
  *
+ * @see org.apache.tapestry5.IOCSymbols
  * @since 5.1.0.1
  */
 public interface ParallelExecutor

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java?rev=763398&r1=763397&r2=763398&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/TapestryIOCModule.java
 Wed Apr  8 21:17:16 2009
@@ -399,6 +399,9 @@
             @IntermediateType(TimeInterval.class)
             int keepAliveMillis,
 
+            @Symbol(IOCSymbols.THREAD_POOL_ENABLED)
+            boolean threadPoolEnabled,
+
             PerthreadManager perthreadManager,
 
             RegistryShutdownHub shutdownHub,
@@ -406,6 +409,9 @@
             ThunkCreator thunkCreator)
     {
 
+        if (!threadPoolEnabled)
+            return new NonParallelExecutor();
+
         final ThreadPoolExecutor executorService = new 
ThreadPoolExecutor(coreSize, maxSize,
                                                                           
keepAliveMillis, TimeUnit.MILLISECONDS,
                                                                           new 
LinkedBlockingQueue(maxSize));
@@ -426,5 +432,6 @@
         configuration.add(IOCSymbols.THREAD_POOL_CORE_SIZE, "3");
         configuration.add(IOCSymbols.THREAD_POOL_MAX_SIZE, "20");
         configuration.add(IOCSymbols.THREAD_POOL_KEEP_ALIVE, "1 m");
+        configuration.add(IOCSymbols.THREAD_POOL_ENABLED, "true");
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/advice.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/advice.apt?rev=763398&r1=763397&r2=763398&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/advice.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/advice.apt Wed Apr  8 
21:17:16 2009
@@ -42,7 +42,7 @@
 
   This is a method that is placed in a module class. Note the terminology: 
<advise> is the verb ("to advise a method")
   and <advice> is the noun ("with this advice"). The
-  
{{{../../apidocs/org/apache/tapestry5/ioc/MethodAdviceReceiver.html}MethodAdviceReceiver}}
+  
{{{../apidocs/org/apache/tapestry5/ioc/MethodAdviceReceiver.html}MethodAdviceReceiver}}
   is a wrapper around the service being advised: you can add advice to some or 
all methods of the service, and also
   obtain the interface of the service.  It is automatically passed into 
service advisor methods.
 
@@ -55,16 +55,16 @@
 
   Service advisor methods are always void methods (this is different than 
{{{decorator.html}service decorator methods}}).
 
-  The {{{../../apidocs/org/apache/tapestry5/ioc/annotations/match.ht...@match}}
+  The {{{../apidocs/org/apache/tapestry5/ioc/annotations/match.ht...@match}}
   annotation indicates that this advice applies to all services (both your 
own, and those defined by Tapestry).
   You will want to narrow down which services are actually targetted in most 
cases.
 
   Note that some services, especially those built-in to Tapestry IoC, are 
marked as
-  
{{{../../apidocs/org/apache/tapestry5/ioc/annotations/PreventServiceDecoration.html}not
 subject to decoration}},
+  
{{{../apidocs/org/apache/tapestry5/ioc/annotations/PreventServiceDecoration.html}not
 subject to decoration}},
   this applies to service advice as well as service decoration.
 
-  The 
{{{../../apidocs/org/apache/tapestry5/ioc/MethodAdvice.html}MethodAdvice}} 
interface is very simple; it receives an
-  {{{../../apidocs/org/apache/tapestry5/ioc/Invocation.html}Invocation}} 
representing a method call. Invocation
+  The {{{../apidocs/org/apache/tapestry5/ioc/MethodAdvice.html}MethodAdvice}} 
interface is very simple; it receives an
+  {{{../apidocs/org/apache/tapestry5/ioc/Invocation.html}Invocation}} 
representing a method call. Invocation
   has methods for inspecting the type and value of the parameters, and for 
overriding the values of the parameters.
 
   The call to proceed() allows the invocation to continue; that is, the 
original method is invoked.  If the method has been advised
@@ -98,7 +98,11 @@
   };
 ----
 
-Logging Advice
+Built-in Advice
+
+Tapestry includes two built-in advisor services.
+
+* Logging Advice
 
   Logging advice is built into Tapestry.  You can apply logging advice to your 
services very easily:
 
@@ -110,10 +114,17 @@
   }
 ---
 
-  
{{{../../apidocs/org/apache/tapestry5/ioc/services/LoggingAdvisor.html}LoggingAdvisor}}
 is
+  
{{{../apidocs/org/apache/tapestry5/ioc/services/LoggingAdvisor.html}LoggingAdvisor}}
 is
   a built-in Tapestry IoC service.  This demonstrates how services can be 
injected into
   service advisor methods.   The Logger parameter is the logger for the 
service being advised.
 
+* Lazy Advice
+
+  
{{{../apidocs/org/apache/tapestry5/ioc/services/LazyAdvisor.html}LazyAdvisor}}
+  makes method invocations lazy: methods that return an interface (rather than 
a value)
+  will not execute immediately; instead, the method invocation is postponed
+  until a method of the return value is invoked.
+
 Matching And Orderering
 
   Each service advice method gets a unique id, obtained by stripping the 
"advise" prefix from the method name.
@@ -123,7 +134,7 @@
 
   In many cases, the order in which the advice is given is very important; for 
example, you may want
   logging first, then transaction management, then security checks.  The
-  {{{../../apidocs/org/apache/tapestry5/ioc/annotations/order.ht...@order}} 
annotation allows you
+  {{{../apidocs/org/apache/tapestry5/ioc/annotations/order.ht...@order}} 
annotation allows you
   to explictly set the order.  
 
 Decorators and Advice
@@ -135,4 +146,3 @@
   will be in effect before any advice (internally, they are two seperate 
steps, with advice being processed and the
   result of that used by the decorators).
 
-

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/parallel.apt
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/parallel.apt?rev=763398&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/parallel.apt (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/parallel.apt Wed Apr  8 
21:17:16 2009
@@ -0,0 +1,56 @@
+  ---
+  Parallel Execution
+  ---
+
+Parallel Execution
+
+  The
+  
{{{../apidocs/org/apache/tapestry5/ioc/services/ParallelExecutor.html}ParallelExecutor}}
+  allows a computation to occur in parallel.
+
+  It can be used in two ways.  First, with an explicit Future:
+
+----
+   Future<String> future = executor.invoke(new Invokable<String>() { ... });
+----
+
+   The executor will submit the Invokable to a thread pool for execution in 
the background.
+
+   The ultimate value of the Invokable is available from invoking get() on the 
Future; this will
+   block until the value is ready.
+
+   Other methods on  Future can cancel the execution, or get the value only if 
it is ready
+   within a timeout.
+
+   The thread pool is started automatically as needed, and will shutdown when 
the Registry
+   itself is shutdown.
+
+   Another alternative will return an object, not a Future:
+
+----
+  RSSFeed feed = executor.invoke(RSSFeed.class, new Invokable<RSSFeed>() { ... 
});
+----
+
+  This only works if the type is an interface.  A proxy for the interface is 
created around
+  the Future object; any invocation on the proxy will invoke get() on the 
Future.
+  
+
+Configuration
+
+  Configuraton symbols are defined in
+  {{{../apidocs/org/apache/tapestry5/ioc/IOCSymbols.html}IOCSymbols}}.
+
+  [tapestry.thread-pool-enabled]
+    If "true", the default, then the thread pool will operate. If "false", then
+    ParallelExecutor's implementation changes to invoke the Invokable 
immediately, not
+    in a pooled thread.
+
+  [tapestry.thread-pool.core-pool-size]
+    Minimum size of the thread pool. Defaults to 3.
+
+  [tapestry.thread-pool.max-pool-size]
+    Maximum number of threads (active or inactive) in the thread pool. 
Defaults to 20.
+
+  [tapestry.thread-pool.keep-alive]
+    Time to keep waiting threads alive. Defaults to "1 m" (one minute). 
+

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/parallel.apt
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml?rev=763398&r1=763397&r2=763398&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml Wed Apr  8 21:17:16 
2009
@@ -64,6 +64,7 @@
             <item name="Ordering" href="order.html"/>
             <item name="Logging" href="logging.html"/>
             <item name="Startup" href="startup.html"/>
+            <item name="Parallel Execution" href="parallel.html"/>
         </menu>
 
 

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutorTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutorTest.java?rev=763398&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutorTest.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutorTest.java
 Wed Apr  8 21:17:16 2009
@@ -0,0 +1,93 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc.internal.services;
+
+import org.apache.tapestry5.ioc.Invokable;
+import org.apache.tapestry5.ioc.Registry;
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.services.ParallelExecutor;
+import org.apache.tapestry5.ioc.test.TestBase;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.Future;
+
+public class NonParallelExecutorTest extends TestBase
+{
+    private Registry registry;
+
+    private ParallelExecutor executor;
+
+    @BeforeClass
+    public void setup()
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.add(NonParallelModule.class);
+
+        registry = builder.build();
+        executor = registry.getService(ParallelExecutor.class);
+    }
+
+    @AfterClass
+    public void cleanup()
+    {
+        registry.shutdown();
+
+        registry = null;
+        executor = null;
+    }
+
+    @Test
+    public void invoke_proxy()
+    {
+        Invokable<String> inv = newMock(Invokable.class);
+
+        String value = "invokable-value";
+
+        expect(inv.invoke()).andReturn(value);
+
+        replay();
+
+        assertSame(executor.invoke(String.class, inv), value);
+
+        verify();
+    }
+
+    @Test
+    public void invoke_with_future() throws Exception
+    {
+        Invokable<String> inv = newMock(Invokable.class);
+
+        String value = "invokable-value";
+
+        expect(inv.invoke()).andReturn(value);
+
+        replay();
+
+        Future<String> future = executor.invoke(inv);
+
+        assertFalse(future.cancel(true));
+        assertFalse(future.isCancelled());
+        assertTrue(future.isDone());
+        assertSame(future.get(), value);
+        assertSame(future.get(0, null), value);
+
+        verify();
+
+    }
+}
+
+

Propchange: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelExecutorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelModule.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelModule.java?rev=763398&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelModule.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelModule.java
 Wed Apr  8 21:17:16 2009
@@ -0,0 +1,26 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc.internal.services;
+
+import org.apache.tapestry5.IOCSymbols;
+import org.apache.tapestry5.ioc.MappedConfiguration;
+
+public class NonParallelModule
+{
+    public static void 
contributeApplicationDefaults(MappedConfiguration<String, String> configuration)
+    {
+        configuration.add(IOCSymbols.THREAD_POOL_ENABLED, "false");
+    }
+}

Propchange: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/NonParallelModule.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to