1 package org.apache.jcs.auxiliary.lateral;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.io.Serializable;
24 import java.rmi.UnmarshalException;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.Set;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.jcs.auxiliary.AuxiliaryCache;
33 import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
34 import org.apache.jcs.auxiliary.lateral.behavior.ILateralCacheService;
35 import org.apache.jcs.engine.CacheAdaptor;
36 import org.apache.jcs.engine.CacheConstants;
37 import org.apache.jcs.engine.CacheEventQueueFactory;
38 import org.apache.jcs.engine.behavior.ICacheElement;
39 import org.apache.jcs.engine.behavior.ICacheEventQueue;
40 import org.apache.jcs.engine.stats.StatElement;
41 import org.apache.jcs.engine.stats.Stats;
42 import org.apache.jcs.engine.stats.behavior.IStatElement;
43 import org.apache.jcs.engine.stats.behavior.IStats;
44
45 /***
46 * Used to queue up update requests to the underlying cache. These requests will be processed in
47 * their order of arrival via the cache event queue processor.
48 */
49 public class LateralCacheNoWait
50 implements AuxiliaryCache
51 {
52 private static final long serialVersionUID = -7251187566116178475L;
53
54 private final static Log log = LogFactory.getLog( LateralCacheNoWait.class );
55
56 private final LateralCache cache;
57
58 private ICacheEventQueue q;
59
60 private int getCount = 0;
61
62 private int removeCount = 0;
63
64 private int putCount = 0;
65
66 /***
67 * Constructs with the given lateral cache, and fires up an event queue for aysnchronous
68 * processing.
69 * <p>
70 * @param cache
71 */
72 public LateralCacheNoWait( LateralCache cache )
73 {
74 this.cache = cache;
75
76 if ( log.isDebugEnabled() )
77 {
78 log.debug( "Constructing LateralCacheNoWait, LateralCache = [" + cache + "]" );
79 }
80
81 CacheEventQueueFactory fact = new CacheEventQueueFactory();
82 this.q = fact.createCacheEventQueue( new CacheAdaptor( cache ), LateralCacheInfo.listenerId, cache
83 .getCacheName(), cache.getAuxiliaryCacheAttributes().getEventQueuePoolName(), cache
84 .getAuxiliaryCacheAttributes().getEventQueueTypeFactoryCode() );
85
86
87
88
89
90
91
92 if ( cache.getStatus() == CacheConstants.STATUS_ERROR )
93 {
94 q.destroy();
95 }
96 }
97
98 /***
99 * @param ce
100 * @throws IOException
101 */
102 public void update( ICacheElement ce )
103 throws IOException
104 {
105 putCount++;
106 try
107 {
108 q.addPutEvent( ce );
109 }
110 catch ( IOException ex )
111 {
112 log.error( ex );
113 q.destroy();
114 }
115 }
116
117 /***
118 * Synchronously reads from the lateral cache.
119 * <p>
120 * @param key
121 * @return ICacheElement if found, else null
122 */
123 public ICacheElement get( Serializable key )
124 {
125 getCount++;
126 if ( this.getStatus() != CacheConstants.STATUS_ERROR )
127 {
128 try
129 {
130 return cache.get( key );
131 }
132 catch ( UnmarshalException ue )
133 {
134 log.debug( "Retrying the get owing to UnmarshalException..." );
135 try
136 {
137 return cache.get( key );
138 }
139 catch ( IOException ex )
140 {
141 log.error( "Failed in retrying the get for the second time." );
142 q.destroy();
143 }
144 }
145 catch ( IOException ex )
146 {
147 q.destroy();
148 }
149 }
150 return null;
151 }
152
153 public Set getGroupKeys( String groupName )
154 {
155 return cache.getGroupKeys( groupName );
156 }
157
158 /***
159 * Adds a remove request to the lateral cache.
160 * <p>
161 * @param key
162 * @return always false
163 */
164 public boolean remove( Serializable key )
165 {
166 removeCount++;
167 try
168 {
169 q.addRemoveEvent( key );
170 }
171 catch ( IOException ex )
172 {
173 log.error( ex );
174 q.destroy();
175 }
176 return false;
177 }
178
179 /*** Adds a removeAll request to the lateral cache. */
180 public void removeAll()
181 {
182 try
183 {
184 q.addRemoveAllEvent();
185 }
186 catch ( IOException ex )
187 {
188 log.error( ex );
189 q.destroy();
190 }
191 }
192
193 /*** Adds a dispose request to the lateral cache. */
194 public void dispose()
195 {
196 try
197 {
198 q.addDisposeEvent();
199 }
200 catch ( IOException ex )
201 {
202 log.error( ex );
203 q.destroy();
204 }
205 }
206
207 /***
208 * No lateral invocation.
209 * <p>
210 * @return The size value
211 */
212 public int getSize()
213 {
214 return cache.getSize();
215 }
216
217 /***
218 * No lateral invocation.
219 * <p>
220 * @return The cacheType value
221 */
222 public int getCacheType()
223 {
224 return cache.getCacheType();
225 }
226
227 /***
228 * Returns the asyn cache status. An error status indicates either the lateral connection is not
229 * available, or the asyn queue has been unexpectedly destroyed. No lateral invokation.
230 * <p>
231 * @return The status value
232 */
233 public int getStatus()
234 {
235 return q.isWorking() ? cache.getStatus() : CacheConstants.STATUS_ERROR;
236 }
237
238 /***
239 * Gets the cacheName attribute of the LateralCacheNoWait object
240 * <p>
241 * @return The cacheName value
242 */
243 public String getCacheName()
244 {
245 return cache.getCacheName();
246 }
247
248 /***
249 * Replaces the lateral cache service handle with the given handle and reset the queue by
250 * starting up a new instance.
251 * <p>
252 * @param lateral
253 */
254 public void fixCache( ILateralCacheService lateral )
255 {
256 cache.fixCache( lateral );
257 resetEventQ();
258 return;
259 }
260
261 /***
262 * Resets the event q by first destroying the existing one and starting up new one.
263 */
264 public void resetEventQ()
265 {
266 if ( q.isWorking() )
267 {
268 q.destroy();
269 }
270 CacheEventQueueFactory fact = new CacheEventQueueFactory();
271 this.q = fact.createCacheEventQueue( new CacheAdaptor( cache ), LateralCacheInfo.listenerId, cache
272 .getCacheName(), cache.getAuxiliaryCacheAttributes().getEventQueuePoolName(), cache
273 .getAuxiliaryCacheAttributes().getEventQueueTypeFactoryCode() );
274 }
275
276 /***
277 * @return Returns the AuxiliaryCacheAttributes.
278 */
279 public AuxiliaryCacheAttributes getAuxiliaryCacheAttributes()
280 {
281 return cache.getAuxiliaryCacheAttributes();
282 }
283
284 /***
285 * getStats
286 * @return String
287 */
288 public String getStats()
289 {
290 return getStatistics().toString();
291 }
292
293
294
295
296
297 public IStats getStatistics()
298 {
299 IStats stats = new Stats();
300 stats.setTypeName( "Lateral Cache No Wait" );
301
302 ArrayList elems = new ArrayList();
303
304
305
306
307
308
309 IStats eqStats = this.q.getStatistics();
310
311 IStatElement[] eqSEs = eqStats.getStatElements();
312 List eqL = Arrays.asList( eqSEs );
313 elems.addAll( eqL );
314
315 IStatElement se = null;
316
317 se = new StatElement();
318 se.setName( "Get Count" );
319 se.setData( "" + this.getCount );
320 elems.add( se );
321
322 se = new StatElement();
323 se.setName( "Remove Count" );
324 se.setData( "" + this.removeCount );
325 elems.add( se );
326
327 se = new StatElement();
328 se.setName( "Put Count" );
329 se.setData( "" + this.putCount );
330 elems.add( se );
331
332
333 IStatElement[] ses = (IStatElement[]) elems.toArray( new StatElement[elems.size()] );
334 stats.setStatElements( ses );
335
336 return stats;
337 }
338
339
340
341
342
343 public String toString()
344 {
345 StringBuffer buf = new StringBuffer();
346 buf.append( " LateralCacheNoWait " );
347 buf.append( " Status = " + this.getStatus() );
348 buf.append( " cache = [" + cache.toString() + "]" );
349 return buf.toString();
350 }
351 }