1 package org.apache.commons.jcs3.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.rmi.UnmarshalException;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.Map.Entry;
29 import java.util.Set;
30 import java.util.stream.Collectors;
31
32 import org.apache.commons.jcs3.auxiliary.AbstractAuxiliaryCache;
33 import org.apache.commons.jcs3.auxiliary.lateral.behavior.ILateralCacheAttributes;
34 import org.apache.commons.jcs3.engine.CacheAdaptor;
35 import org.apache.commons.jcs3.engine.CacheEventQueueFactory;
36 import org.apache.commons.jcs3.engine.CacheInfo;
37 import org.apache.commons.jcs3.engine.CacheStatus;
38 import org.apache.commons.jcs3.engine.behavior.ICacheElement;
39 import org.apache.commons.jcs3.engine.behavior.ICacheEventQueue;
40 import org.apache.commons.jcs3.engine.behavior.ICacheServiceNonLocal;
41 import org.apache.commons.jcs3.engine.stats.StatElement;
42 import org.apache.commons.jcs3.engine.stats.Stats;
43 import org.apache.commons.jcs3.engine.stats.behavior.IStatElement;
44 import org.apache.commons.jcs3.engine.stats.behavior.IStats;
45 import org.apache.commons.jcs3.log.Log;
46 import org.apache.commons.jcs3.log.LogManager;
47
48
49
50
51
52 public class LateralCacheNoWait<K, V>
53 extends AbstractAuxiliaryCache<K, V>
54 {
55
56 private static final Log log = LogManager.getLog( LateralCacheNoWait.class );
57
58
59 private final LateralCache<K, V> cache;
60
61
62 private String identityKey;
63
64
65 private ICacheEventQueue<K, V> eventQueue;
66
67
68 private int getCount;
69
70
71 private int removeCount;
72
73
74 private int putCount;
75
76
77
78
79
80
81
82 public LateralCacheNoWait( final LateralCache<K, V> cache )
83 {
84 this.cache = cache;
85 this.identityKey = cache.getCacheName();
86 this.setCacheEventLogger(cache.getCacheEventLogger());
87 this.setElementSerializer(cache.getElementSerializer());
88
89 log.debug( "Constructing LateralCacheNoWait, LateralCache = [{0}]", cache );
90
91 final CacheEventQueueFactory<K, V> fact = new CacheEventQueueFactory<>();
92 this.eventQueue = fact.createCacheEventQueue( new CacheAdaptor<>( cache ),
93 CacheInfo.listenerId, cache.getCacheName(),
94 getAuxiliaryCacheAttributes().getEventQueuePoolName(),
95 getAuxiliaryCacheAttributes().getEventQueueType() );
96
97
98
99
100
101
102
103 if ( cache.getStatus() == CacheStatus.ERROR )
104 {
105 eventQueue.destroy();
106 }
107 }
108
109
110
111
112
113
114
115 public String getIdentityKey()
116 {
117 return identityKey;
118 }
119
120
121
122
123
124
125
126 public void setIdentityKey(String identityKey)
127 {
128 this.identityKey = identityKey;
129 }
130
131
132
133
134
135 @Override
136 public void update( final ICacheElement<K, V> ce )
137 throws IOException
138 {
139 putCount++;
140 try
141 {
142 eventQueue.addPutEvent( ce );
143 }
144 catch ( final IOException ex )
145 {
146 log.error( ex );
147 eventQueue.destroy();
148 }
149 }
150
151
152
153
154
155
156
157 @Override
158 public ICacheElement<K, V> get( final K key )
159 {
160 getCount++;
161 if ( this.getStatus() != CacheStatus.ERROR )
162 {
163 try
164 {
165 return cache.get( key );
166 }
167 catch ( final UnmarshalException ue )
168 {
169 log.debug( "Retrying the get owing to UnmarshalException..." );
170 try
171 {
172 return cache.get( key );
173 }
174 catch ( final IOException ex )
175 {
176 log.error( "Failed in retrying the get for the second time." );
177 eventQueue.destroy();
178 }
179 }
180 catch ( final IOException ex )
181 {
182 eventQueue.destroy();
183 }
184 }
185 return null;
186 }
187
188
189
190
191
192
193
194
195 @Override
196 public Map<K, ICacheElement<K, V>> getMultiple(final Set<K> keys)
197 {
198 if ( keys != null && !keys.isEmpty() )
199 {
200 return keys.stream()
201 .collect(Collectors.toMap(
202 key -> key,
203 this::get)).entrySet().stream()
204 .filter(entry -> entry.getValue() != null)
205 .collect(Collectors.toMap(
206 Entry::getKey,
207 Entry::getValue));
208 }
209
210 return new HashMap<>();
211 }
212
213
214
215
216
217
218
219 @Override
220 public Map<K, ICacheElement<K, V>> getMatching(final String pattern)
221 {
222 getCount++;
223 if ( this.getStatus() != CacheStatus.ERROR )
224 {
225 try
226 {
227 return cache.getMatching( pattern );
228 }
229 catch ( final UnmarshalException ue )
230 {
231 log.debug( "Retrying the get owing to UnmarshalException." );
232 try
233 {
234 return cache.getMatching( pattern );
235 }
236 catch ( final IOException ex )
237 {
238 log.error( "Failed in retrying the get for the second time." );
239 eventQueue.destroy();
240 }
241 }
242 catch ( final IOException ex )
243 {
244 eventQueue.destroy();
245 }
246 }
247 return Collections.emptyMap();
248 }
249
250
251
252
253
254
255 @Override
256 public Set<K> getKeySet() throws IOException
257 {
258 try
259 {
260 return cache.getKeySet();
261 }
262 catch ( final IOException ex )
263 {
264 log.error( ex );
265 eventQueue.destroy();
266 }
267 return Collections.emptySet();
268 }
269
270
271
272
273
274
275
276 @Override
277 public boolean remove( final K key )
278 {
279 removeCount++;
280 try
281 {
282 eventQueue.addRemoveEvent( key );
283 }
284 catch ( final IOException ex )
285 {
286 log.error( ex );
287 eventQueue.destroy();
288 }
289 return false;
290 }
291
292
293 @Override
294 public void removeAll()
295 {
296 try
297 {
298 eventQueue.addRemoveAllEvent();
299 }
300 catch ( final IOException ex )
301 {
302 log.error( ex );
303 eventQueue.destroy();
304 }
305 }
306
307
308 @Override
309 public void dispose()
310 {
311 try
312 {
313 eventQueue.addDisposeEvent();
314 }
315 catch ( final IOException ex )
316 {
317 log.error( ex );
318 eventQueue.destroy();
319 }
320 }
321
322
323
324
325
326
327 @Override
328 public int getSize()
329 {
330 return cache.getSize();
331 }
332
333
334
335
336
337
338 @Override
339 public CacheType getCacheType()
340 {
341 return cache.getCacheType();
342 }
343
344
345
346
347
348
349
350 @Override
351 public CacheStatus getStatus()
352 {
353 return eventQueue.isWorking() ? cache.getStatus() : CacheStatus.ERROR;
354 }
355
356
357
358
359
360
361 @Override
362 public String getCacheName()
363 {
364 return cache.getCacheName();
365 }
366
367
368
369
370
371
372
373 public void fixCache( final ICacheServiceNonLocal<K, V> lateral )
374 {
375 cache.fixCache( lateral );
376 resetEventQ();
377 }
378
379
380
381
382 public void resetEventQ()
383 {
384 if ( eventQueue.isWorking() )
385 {
386 eventQueue.destroy();
387 }
388 final CacheEventQueueFactory<K, V> fact = new CacheEventQueueFactory<>();
389 this.eventQueue = fact.createCacheEventQueue( new CacheAdaptor<>( cache ),
390 CacheInfo.listenerId, cache.getCacheName(),
391 getAuxiliaryCacheAttributes().getEventQueuePoolName(),
392 getAuxiliaryCacheAttributes().getEventQueueType() );
393 }
394
395
396
397
398 @Override
399 public ILateralCacheAttributes getAuxiliaryCacheAttributes()
400 {
401 return cache.getAuxiliaryCacheAttributes();
402 }
403
404
405
406
407
408 @Override
409 public String getStats()
410 {
411 return getStatistics().toString();
412 }
413
414
415
416
417
418
419 @Override
420 public String getEventLoggingExtraInfo()
421 {
422 return "Lateral Cache No Wait";
423 }
424
425
426
427
428 @Override
429 public IStats getStatistics()
430 {
431 final IStats stats = new Stats();
432 stats.setTypeName( "Lateral Cache No Wait" );
433
434
435 final IStats eqStats = this.eventQueue.getStatistics();
436 final ArrayList<IStatElement<?>> elems = new ArrayList<>(eqStats.getStatElements());
437
438 elems.add(new StatElement<>( "Get Count", Integer.valueOf(this.getCount) ) );
439 elems.add(new StatElement<>( "Remove Count", Integer.valueOf(this.removeCount) ) );
440 elems.add(new StatElement<>( "Put Count", Integer.valueOf(this.putCount) ) );
441 elems.add(new StatElement<>( "Attributes", cache.getAuxiliaryCacheAttributes() ) );
442
443 stats.setStatElements( elems );
444
445 return stats;
446 }
447
448
449
450
451 @Override
452 public String toString()
453 {
454 final StringBuilder buf = new StringBuilder();
455 buf.append( " LateralCacheNoWait " );
456 buf.append( " Status = " + this.getStatus() );
457 buf.append( " cache = [" + cache.toString() + "]" );
458 return buf.toString();
459 }
460 }