001 // Copyright 2009, 2010, 2011 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry5.ioc.internal.services;
016
017 import java.util.concurrent.Callable;
018 import java.util.concurrent.ExecutorService;
019 import java.util.concurrent.Future;
020
021 import org.apache.tapestry5.ioc.Invokable;
022 import org.apache.tapestry5.ioc.ObjectCreator;
023 import org.apache.tapestry5.ioc.services.ParallelExecutor;
024 import org.apache.tapestry5.ioc.services.PerthreadManager;
025 import org.apache.tapestry5.ioc.services.ThunkCreator;
026
027 public class ParallelExecutorImpl implements ParallelExecutor
028 {
029 private final ThunkCreator thunkCreator;
030
031 private final ExecutorService executorService;
032
033 private final PerthreadManager perthreadManager;
034
035 public ParallelExecutorImpl(ExecutorService executorService, ThunkCreator thunkCreator,
036 PerthreadManager perthreadManager)
037 {
038 this.executorService = executorService;
039 this.thunkCreator = thunkCreator;
040 this.perthreadManager = perthreadManager;
041 }
042
043 public <T> Future<T> invoke(Invokable<T> invocable)
044 {
045 assert invocable != null;
046
047 return executorService.submit(toCallable(invocable));
048 }
049
050 private <T> Callable<T> toCallable(final Invokable<T> invocable)
051 {
052 return new Callable<T>()
053 {
054 public T call() throws Exception
055 {
056 try
057 {
058 return invocable.invoke();
059 }
060 finally
061 {
062 perthreadManager.cleanup();
063 }
064 }
065 };
066 }
067
068 public <T> T invoke(Class<T> proxyType, Invokable<T> invocable)
069 {
070 final Future<T> future = invoke(invocable);
071
072 ObjectCreator<T> creator = new ObjectCreator<T>()
073 {
074 public T createObject()
075 {
076 try
077 {
078 return future.get();
079 }
080 catch (Exception ex)
081 {
082 throw new RuntimeException(ex);
083 }
084 }
085 };
086
087 String description = String.format("FutureThunk[%s]", proxyType.getName());
088
089 return thunkCreator.createThunk(proxyType, new CachingObjectCreator(creator), description);
090 }
091 }