%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.jcs.auxiliary.lateral.socket.tcp.LateralTCPCacheManager |
|
|
1 | package org.apache.jcs.auxiliary.lateral.socket.tcp; |
|
2 | ||
3 | /* |
|
4 | * Licensed to the Apache Software Foundation (ASF) under one |
|
5 | * or more contributor license agreements. See the NOTICE file |
|
6 | * distributed with this work for additional information |
|
7 | * regarding copyright ownership. The ASF licenses this file |
|
8 | * to you under the Apache License, Version 2.0 (the |
|
9 | * "License"); you may not use this file except in compliance |
|
10 | * with the License. You may obtain a copy of the License at |
|
11 | * |
|
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
13 | * |
|
14 | * Unless required by applicable law or agreed to in writing, |
|
15 | * software distributed under the License is distributed on an |
|
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
17 | * KIND, either express or implied. See the License for the |
|
18 | * specific language governing permissions and limitations |
|
19 | * under the License. |
|
20 | */ |
|
21 | ||
22 | import java.io.IOException; |
|
23 | import java.util.HashMap; |
|
24 | import java.util.Map; |
|
25 | ||
26 | import org.apache.commons.logging.Log; |
|
27 | import org.apache.commons.logging.LogFactory; |
|
28 | import org.apache.jcs.auxiliary.AuxiliaryCache; |
|
29 | import org.apache.jcs.auxiliary.lateral.LateralCache; |
|
30 | import org.apache.jcs.auxiliary.lateral.LateralCacheAbstractManager; |
|
31 | import org.apache.jcs.auxiliary.lateral.LateralCacheAttributes; |
|
32 | import org.apache.jcs.auxiliary.lateral.LateralCacheMonitor; |
|
33 | import org.apache.jcs.auxiliary.lateral.LateralCacheNoWait; |
|
34 | import org.apache.jcs.auxiliary.lateral.LateralCacheWatchRepairable; |
|
35 | import org.apache.jcs.auxiliary.lateral.ZombieLateralCacheService; |
|
36 | import org.apache.jcs.auxiliary.lateral.ZombieLateralCacheWatch; |
|
37 | import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheListener; |
|
38 | import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheManager; |
|
39 | import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheService; |
|
40 | import org.apache.jcs.auxiliary.lateral.socket.tcp.behavior.ITCPLateralCacheAttributes; |
|
41 | import org.apache.jcs.engine.behavior.ICompositeCacheManager; |
|
42 | ||
43 | /** |
|
44 | * Creates lateral caches. Lateral caches are primarily used for removing non |
|
45 | * laterally configured caches. Non laterally configured cache regions should |
|
46 | * still be able to participate in removal. But if there is a non laterally |
|
47 | * configured cache hub, then lateral removals may be necessary. For flat |
|
48 | * webserver production environments, without a strong machine at the app server |
|
49 | * level, distribution and search may need to occur at the lateral cache level. |
|
50 | * This is currently not implemented in the lateral cache. |
|
51 | * <p> |
|
52 | * |
|
53 | * @TODO: - need freeCache, release, getStats - need to find an interface |
|
54 | * acceptable for all - cache managers or a manager within a type |
|
55 | */ |
|
56 | public class LateralTCPCacheManager |
|
57 | extends LateralCacheAbstractManager |
|
58 | { |
|
59 | private static final long serialVersionUID = -9213011856644392480L; |
|
60 | ||
61 | 28 | private final static Log log = LogFactory.getLog( LateralTCPCacheManager.class ); |
62 | ||
63 | private static LateralCacheMonitor monitor; |
|
64 | ||
65 | /** Address to instance map. */ |
|
66 | 14 | protected static Map instances = new HashMap(); |
67 | ||
68 | /** ITCPLateralCacheAttributes */ |
|
69 | protected ITCPLateralCacheAttributes lca; |
|
70 | ||
71 | private int clients; |
|
72 | ||
73 | /** |
|
74 | * Handle to the lateral cache service; or a zombie handle if failed to |
|
75 | * connect. |
|
76 | */ |
|
77 | private ILateralCacheService lateralService; |
|
78 | ||
79 | /** |
|
80 | * Wrapper of the lateral cache watch service; or wrapper of a zombie |
|
81 | * service if failed to connect. |
|
82 | */ |
|
83 | private LateralCacheWatchRepairable lateralWatch; |
|
84 | ||
85 | /** This is set in the constructor. */ |
|
86 | private ICompositeCacheManager cacheMgr; |
|
87 | ||
88 | /** |
|
89 | * Returns an instance of the LateralCacheManager. |
|
90 | * <p> |
|
91 | * @param lca |
|
92 | * @param cacheMgr |
|
93 | * this allows the auxiliary to be passed a cache manager. |
|
94 | * @return |
|
95 | */ |
|
96 | public static LateralTCPCacheManager getInstance( ITCPLateralCacheAttributes lca, ICompositeCacheManager cacheMgr ) |
|
97 | { |
|
98 | 27 | LateralTCPCacheManager ins = (LateralTCPCacheManager) instances.get( lca.toString() ); |
99 | 27 | synchronized ( instances ) |
100 | { |
|
101 | 27 | if ( ins == null ) |
102 | { |
|
103 | 14 | log.info( "Instance for [" + lca.toString() + "] is null, creating" ); |
104 | ||
105 | 14 | ins = (LateralTCPCacheManager) instances.get( lca.toString() ); |
106 | 14 | if ( ins == null ) |
107 | { |
|
108 | 14 | ins = new LateralTCPCacheManager( lca, cacheMgr ); |
109 | 14 | instances.put( lca.toString(), ins ); |
110 | } |
|
111 | } |
|
112 | 27 | createMonitor( ins ); |
113 | 27 | } |
114 | 27 | ins.clients++; |
115 | ||
116 | 27 | return ins; |
117 | } |
|
118 | ||
119 | /** |
|
120 | * The monitor needs reference to one instance, actually just a type. |
|
121 | * <p> |
|
122 | * TODO refactor this. |
|
123 | * <p> |
|
124 | * @param instance |
|
125 | */ |
|
126 | private static synchronized void createMonitor( ILateralCacheManager instance ) |
|
127 | { |
|
128 | // only want one monitor per lateral type |
|
129 | // Fires up the monitoring daemon. |
|
130 | 41 | if ( monitor == null ) |
131 | { |
|
132 | 14 | monitor = new LateralCacheMonitor( instance ); |
133 | // Should never be null |
|
134 | 14 | if ( monitor != null ) |
135 | { |
|
136 | 14 | Thread t = new Thread( monitor ); |
137 | 14 | t.setDaemon( true ); |
138 | 14 | t.start(); |
139 | } |
|
140 | } |
|
141 | 41 | } |
142 | ||
143 | /** |
|
144 | * Constructor for the LateralCacheManager object. |
|
145 | * <p> |
|
146 | * @param lcaA |
|
147 | * @param cacheMgr |
|
148 | */ |
|
149 | private LateralTCPCacheManager( ITCPLateralCacheAttributes lcaA, ICompositeCacheManager cacheMgr ) |
|
150 | 14 | { |
151 | 14 | this.lca = lcaA; |
152 | ||
153 | 14 | this.cacheMgr = cacheMgr; |
154 | ||
155 | 14 | if ( log.isDebugEnabled() ) |
156 | { |
|
157 | 0 | log.debug( "Creating lateral cache service, lca = " + this.lca ); |
158 | } |
|
159 | ||
160 | // Create the service |
|
161 | try |
|
162 | { |
|
163 | 14 | if ( log.isInfoEnabled() ) |
164 | { |
|
165 | 14 | log.info( "Creating TCP service, lca = " + this.lca ); |
166 | } |
|
167 | 14 | this.lateralService = new LateralTCPService( class="keyword">this.lca ); |
168 | ||
169 | 0 | if ( this.lateralService == null ) |
170 | { |
|
171 | 0 | log.error( "No service created, must zombie" ); |
172 | 0 | throw new Exception( "No service created for lateral cache." ); |
173 | } |
|
174 | ||
175 | 0 | this.lateralWatch = new LateralCacheWatchRepairable(); |
176 | 0 | this.lateralWatch.setCacheWatch( new ZombieLateralCacheWatch() ); |
177 | } |
|
178 | 14 | catch ( Exception ex ) |
179 | { |
|
180 | // Failed to connect to the lateral server. |
|
181 | // Configure this LateralCacheManager instance to use the |
|
182 | // "zombie" services. |
|
183 | 14 | log.error( "Failure, lateral instance will use zombie service", ex ); |
184 | ||
185 | 14 | this.lateralService = new ZombieLateralCacheService(); |
186 | 14 | this.lateralWatch = new LateralCacheWatchRepairable(); |
187 | 14 | this.lateralWatch.setCacheWatch( new ZombieLateralCacheWatch() ); |
188 | ||
189 | // Notify the cache monitor about the error, and kick off |
|
190 | // the recovery process. |
|
191 | 14 | createMonitor( this ); |
192 | 14 | monitor.notifyError(); |
193 | 0 | } |
194 | 14 | } |
195 | ||
196 | /** |
|
197 | * Adds the lateral cache listener to the underlying cache-watch service. |
|
198 | * <p> |
|
199 | * @param cacheName |
|
200 | * The feature to be added to the LateralCacheListener attribute |
|
201 | * @param listener |
|
202 | * The feature to be added to the LateralCacheListener attribute |
|
203 | * @exception IOException |
|
204 | */ |
|
205 | public void addLateralCacheListener( String cacheName, ILateralCacheListener listener ) |
|
206 | throws IOException |
|
207 | { |
|
208 | 26 | synchronized ( this.caches ) |
209 | { |
|
210 | 26 | this.lateralWatch.addCacheListener( cacheName, listener ); |
211 | 26 | } |
212 | 26 | } |
213 | ||
214 | /** |
|
215 | * Called to access a precreated region or construct one with defaults. |
|
216 | * Since all aux cache access goes through the manager, this will never be |
|
217 | * called. |
|
218 | * <p> |
|
219 | * After getting the manager instance for a server, the factory gets a cache |
|
220 | * for the region name it is constructing. |
|
221 | * <p> |
|
222 | * There should be one manager per server and one cache per region per |
|
223 | * manager. |
|
224 | * <p> |
|
225 | * @return AuxiliaryCache |
|
226 | * @param cacheName |
|
227 | */ |
|
228 | public AuxiliaryCache getCache( String cacheName ) |
|
229 | { |
|
230 | 27 | LateralCacheNoWait lateralNoWait = null; |
231 | 1 | synchronized ( this.caches ) |
232 | { |
|
233 | 26 | lateralNoWait = (LateralCacheNoWait) this.caches.get( cacheName ); |
234 | 26 | if ( lateralNoWait == null ) |
235 | { |
|
236 | 26 | LateralCacheAttributes attr = (LateralCacheAttributes) lca.copy(); |
237 | 26 | attr.setCacheName( cacheName ); |
238 | ||
239 | 26 | LateralCache cache = new LateralCache( attr, this.lateralService, monitor ); |
240 | 26 | if ( log.isDebugEnabled() ) |
241 | { |
|
242 | 0 | log.debug( "Created cache for noWait, cache [" + cache + "]" ); |
243 | } |
|
244 | 26 | lateralNoWait = new LateralCacheNoWait( cache ); |
245 | 26 | this.caches.put( cacheName, lateralNoWait ); |
246 | ||
247 | 26 | if ( log.isInfoEnabled() ) |
248 | { |
|
249 | 26 | log.info( "Created LateralCacheNoWait for [" + this.lca + "] LateralCacheNoWait = [" |
250 | + lateralNoWait + "]" ); |
|
251 | } |
|
252 | } |
|
253 | 26 | } |
254 | ||
255 | // don't create a listener if we are not receiving. |
|
256 | 26 | if ( lca.isReceive() ) |
257 | { |
|
258 | try |
|
259 | { |
|
260 | 26 | addLateralCacheListener( cacheName, LateralTCPListener.getInstance( this.lca, cacheMgr ) ); |
261 | } |
|
262 | 0 | catch ( IOException ioe ) |
263 | { |
|
264 | 0 | log.error( "Problem creating lateral listener", ioe ); |
265 | } |
|
266 | 0 | catch ( Exception e ) |
267 | { |
|
268 | 0 | log.error( "Problem creating lateral listener", e ); |
269 | 26 | } |
270 | 0 | } |
271 | else |
|
272 | { |
|
273 | 0 | if ( log.isDebugEnabled() ) |
274 | { |
|
275 | 0 | log.debug( "Not creating a listener since we are not receiving." ); |
276 | } |
|
277 | } |
|
278 | // TODO: need listener repair |
|
279 | ||
280 | 26 | return lateralNoWait; |
281 | } |
|
282 | ||
283 | /* |
|
284 | * (non-Javadoc) |
|
285 | * |
|
286 | * @see org.apache.jcs.auxiliary.lateral.LateralCacheAbstractManager#getInstances() |
|
287 | */ |
|
288 | public Map getInstances() |
|
289 | { |
|
290 | 28 | return instances; |
291 | } |
|
292 | ||
293 | /* |
|
294 | * (non-Javadoc) |
|
295 | * |
|
296 | * @see org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheManager#fixService() |
|
297 | */ |
|
298 | public Object fixService() |
|
299 | throws IOException |
|
300 | { |
|
301 | 0 | Object service = null; |
302 | try |
|
303 | { |
|
304 | 0 | service = new LateralTCPService( lca ); |
305 | } |
|
306 | 0 | catch ( Exception ex ) |
307 | { |
|
308 | 0 | log.error( "Can't fix " + ex.getMessage() ); |
309 | 0 | throw new IOException( "Can't fix " + ex.getMessage() ); |
310 | 0 | } |
311 | 0 | return service; |
312 | } |
|
313 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |