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 015package org.apache.tapestry5.ioc.internal.services; 016 017import java.util.concurrent.Callable; 018import java.util.concurrent.ExecutorService; 019import java.util.concurrent.Future; 020 021import org.apache.tapestry5.ioc.Invokable; 022import org.apache.tapestry5.ioc.ObjectCreator; 023import org.apache.tapestry5.ioc.services.ParallelExecutor; 024import org.apache.tapestry5.ioc.services.PerthreadManager; 025import org.apache.tapestry5.ioc.services.ThunkCreator; 026 027public 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 @Override 044 public <T> Future<T> invoke(Invokable<T> invocable) 045 { 046 assert invocable != null; 047 048 return executorService.submit(toCallable(invocable)); 049 } 050 051 private <T> Callable<T> toCallable(final Invokable<T> invocable) 052 { 053 return new Callable<T>() 054 { 055 @Override 056 public T call() throws Exception 057 { 058 try 059 { 060 return invocable.invoke(); 061 } 062 finally 063 { 064 perthreadManager.cleanup(); 065 } 066 } 067 }; 068 } 069 070 @Override 071 public <T> T invoke(Class<T> proxyType, Invokable<T> invocable) 072 { 073 final Future<T> future = invoke(invocable); 074 075 ObjectCreator<T> creator = new ObjectCreator<T>() 076 { 077 @Override 078 public T createObject() 079 { 080 try 081 { 082 return future.get(); 083 } 084 catch (Exception ex) 085 { 086 throw new RuntimeException(ex); 087 } 088 } 089 }; 090 091 String description = String.format("FutureThunk[%s]", proxyType.getName()); 092 093 return thunkCreator.createThunk(proxyType, new CachingObjectCreator(creator), description); 094 } 095}