1 package org.apache.onami.lifecycle.warmup;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.google.inject.ConfigurationException;
23 import com.google.inject.TypeLiteral;
24 import com.google.inject.spi.Dependency;
25 import com.google.inject.spi.InjectionPoint;
26 import jsr166y.RecursiveAction;
27 import org.apache.onami.lifecycle.core.StageHandler;
28 import org.apache.onami.lifecycle.core.Stageable;
29
30 import java.util.ArrayList;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35 import java.util.concurrent.ConcurrentMap;
36
37
38
39
40 class WarmUpTask
41 extends RecursiveAction
42 {
43 private final StageHandler stageHandler;
44
45 private final TypeLiteral<?> typeLiteral;
46
47 private final Map<TypeLiteral<?>, Set<Stageable>> reverseLookup;
48
49 private final ConcurrentMap<TypeLiteral<?>, WarmUpTask> inProgress;
50
51 static final TypeLiteral<?> ROOT = new TypeLiteral<Object>(){};
52
53
54
55
56
57
58
59 WarmUpTask( StageHandler stageHandler, TypeLiteral<?> typeLiteral,
60 Map<TypeLiteral<?>, Set<Stageable>> reverseLookup, ConcurrentMap<TypeLiteral<?>, WarmUpTask> inProgress )
61 {
62 this.stageHandler = stageHandler;
63 this.typeLiteral = typeLiteral;
64 this.reverseLookup = reverseLookup;
65 this.inProgress = inProgress;
66 }
67
68 @Override
69 protected void compute()
70 {
71 List<WarmUpTask> tasksToJoin = new ArrayList<WarmUpTask>();
72 if ( typeLiteral == ROOT )
73 {
74
75 computeRoot( tasksToJoin );
76 }
77 else
78 {
79 internalCompute( tasksToJoin );
80 }
81
82
83 for ( WarmUpTask task : tasksToJoin )
84 {
85 task.join();
86 }
87
88
89
90 Set<Stageable> stageables = reverseLookup.get( typeLiteral );
91 if ( stageables != null )
92 {
93 for ( Stageable stageable : stageables )
94 {
95 if ( Thread.currentThread().isInterrupted() )
96 {
97
98
99 break;
100 }
101 stageable.stage( stageHandler );
102 }
103 }
104 }
105
106 private void computeRoot( List<WarmUpTask> tasksToJoin )
107 {
108 for ( TypeLiteral<?> typeLiteral : reverseLookup.keySet() )
109 {
110 WarmUpTask warmUpTask = new WarmUpTask( stageHandler, typeLiteral, reverseLookup, inProgress );
111 startTask( tasksToJoin, warmUpTask );
112 }
113 }
114
115 private void internalCompute( List<WarmUpTask> tasksToJoin )
116 {
117 List<WarmUpTask> childTasks = new ArrayList<WarmUpTask>();
118 addDependency( childTasks, getConstructorInjectionPoint( typeLiteral ) );
119 for ( InjectionPoint injectionPoint : getMethodInjectionPoints( typeLiteral ) )
120 {
121 addDependency( childTasks, injectionPoint );
122 }
123
124 for ( WarmUpTask childTask : childTasks )
125 {
126 startTask( tasksToJoin, childTask );
127 }
128 }
129
130 private void startTask( List<WarmUpTask> tasksToJoin, WarmUpTask childTask )
131 {
132 WarmUpTask existingTask = inProgress.putIfAbsent( childTask.typeLiteral, childTask );
133 if ( existingTask == null )
134 {
135 childTask.fork();
136 tasksToJoin.add( childTask );
137 }
138 else
139 {
140 tasksToJoin.add( existingTask );
141 }
142 }
143
144 private void addDependency( List<WarmUpTask> childTasks, InjectionPoint injectionPoint )
145 {
146 if ( injectionPoint != null )
147 {
148 List<Dependency<?>> dependencies = injectionPoint.getDependencies();
149 for ( Dependency<?> dependency : dependencies )
150 {
151
152
153
154 TypeLiteral<?> dependencyTypeLiteral = dependency.getKey().getTypeLiteral();
155 childTasks.add(
156 new WarmUpTask( stageHandler, dependencyTypeLiteral, reverseLookup, inProgress ) );
157 }
158 }
159 }
160
161 private Set<InjectionPoint> getMethodInjectionPoints( TypeLiteral<?> type )
162 {
163 try
164 {
165 return InjectionPoint.forInstanceMethodsAndFields( type );
166 }
167 catch ( ConfigurationException e )
168 {
169
170 }
171 return new HashSet<InjectionPoint>();
172 }
173
174 private InjectionPoint getConstructorInjectionPoint( TypeLiteral<?> type )
175 {
176 try
177 {
178 return InjectionPoint.forConstructorOf( type );
179 }
180 catch ( ConfigurationException e )
181 {
182
183 }
184 return null;
185 }
186 }