1 package org.apache.commons.jcs.auxiliary.lateral;
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.util.Map;
23 import java.util.concurrent.ConcurrentHashMap;
24
25 import org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheMonitor;
26 import org.apache.commons.jcs.auxiliary.lateral.socket.tcp.LateralTCPCacheFactory;
27 import org.apache.commons.jcs.auxiliary.lateral.socket.tcp.behavior.ITCPLateralCacheAttributes;
28 import org.apache.commons.jcs.engine.CacheStatus;
29 import org.apache.commons.jcs.engine.ZombieCacheServiceNonLocal;
30 import org.apache.commons.jcs.engine.behavior.ICacheServiceNonLocal;
31
32 /**
33 * Used to monitor and repair any failed connection for the lateral cache service. By default the
34 * monitor operates in a failure driven mode. That is, it goes into a wait state until there is an
35 * error. Upon the notification of a connection error, the monitor changes to operate in a time
36 * driven mode. That is, it attempts to recover the connections on a periodic basis. When all failed
37 * connections are restored, it changes back to the failure driven mode.
38 */
39 public class LateralCacheMonitor extends AbstractAuxiliaryCacheMonitor
40 {
41 /**
42 * Map of caches to monitor
43 */
44 private ConcurrentHashMap<String, LateralCacheNoWait<?, ?>> caches;
45
46 /**
47 * Reference to the factory
48 */
49 private LateralTCPCacheFactory factory;
50
51 /**
52 * Allows close classes, ie testers to set the idle period to something testable.
53 * <p>
54 * @param idlePeriod
55 */
56 protected static void forceShortIdlePeriod( long idlePeriod )
57 {
58 LateralCacheMonitor.idlePeriod = idlePeriod;
59 }
60
61 /**
62 * Constructor for the LateralCacheMonitor object
63 * <p>
64 * It's the clients responsibility to decide how many of these there will be.
65 *
66 * @param factory a reference to the factory that manages the service instances
67 */
68 public LateralCacheMonitor(LateralTCPCacheFactory factory)
69 {
70 super("JCS-LateralCacheMonitor");
71 this.factory = factory;
72 this.caches = new ConcurrentHashMap<String, LateralCacheNoWait<?,?>>();
73 setIdlePeriod(20000L);
74 }
75
76 /**
77 * Add a cache to be monitored
78 *
79 * @param cache the cache
80 */
81 public void addCache(LateralCacheNoWait<?, ?> cache)
82 {
83 this.caches.put(cache.getCacheName(), cache);
84
85 // if not yet started, go ahead
86 if (this.getState() == Thread.State.NEW)
87 {
88 this.start();
89 }
90 }
91
92 /**
93 * Clean up all resources before shutdown
94 */
95 @Override
96 public void dispose()
97 {
98 this.caches.clear();
99 }
100
101 /**
102 * Main processing method for the LateralCacheMonitor object
103 */
104 @Override
105 public void doWork()
106 {
107 // Monitor each cache instance one after the other.
108 log.info( "Number of caches to monitor = " + caches.size() );
109 //for
110 for (Map.Entry<String, LateralCacheNoWait<?, ?>> entry : caches.entrySet())
111 {
112 String cacheName = entry.getKey();
113
114 @SuppressWarnings("unchecked") // Downcast to match service
115 LateralCacheNoWait<Object, Object> c = (LateralCacheNoWait<Object, Object>) entry.getValue();
116 if ( c.getStatus() == CacheStatus.ERROR )
117 {
118 log.info( "Found LateralCacheNoWait in error, " + cacheName );
119
120 ITCPLateralCacheAttributes lca = (ITCPLateralCacheAttributes)c.getAuxiliaryCacheAttributes();
121
122 // Get service instance
123 ICacheServiceNonLocal<Object, Object> cacheService = factory.getCSNLInstance(lca);
124
125 // If we can't fix them, just skip and re-try in the
126 // next round.
127 if (cacheService instanceof ZombieCacheServiceNonLocal)
128 {
129 continue;
130 }
131
132 c.fixCache(cacheService);
133 }
134 }
135 }
136 }