1 package org.apache.commons.jcs.auxiliary.remote.http.client;
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.io.Serializable;
24 import java.util.concurrent.ConcurrentHashMap;
25
26 import org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheMonitor;
27 import org.apache.commons.jcs.auxiliary.remote.http.client.behavior.IRemoteHttpCacheClient;
28 import org.apache.commons.jcs.engine.CacheStatus;
29
30 /**
31 * Upon the notification of a connection error, the monitor changes to operate in a time driven
32 * mode. That is, it attempts to recover the connections on a periodic basis. When all failed
33 * connections are restored, it changes back to the failure driven mode.
34 */
35 public class RemoteHttpCacheMonitor extends AbstractAuxiliaryCacheMonitor
36 {
37 /** Set of remote caches to monitor. This are added on error, if not before. */
38 private final ConcurrentHashMap<RemoteHttpCache<?, ?>, RemoteHttpCache<?, ?>> remoteHttpCaches;
39
40 /** Factory instance */
41 private RemoteHttpCacheFactory factory = null;
42
43 /**
44 * Constructor for the RemoteCacheMonitor object
45 *
46 * @param factory the factory to set
47 */
48 public RemoteHttpCacheMonitor(RemoteHttpCacheFactory factory)
49 {
50 super("JCS-RemoteHttpCacheMonitor");
51 this.factory = factory;
52 this.remoteHttpCaches = new ConcurrentHashMap<RemoteHttpCache<?, ?>, RemoteHttpCache<?, ?>>();
53 setIdlePeriod(3000L);
54 }
55
56 /**
57 * Notifies the cache monitor that an error occurred, and kicks off the error recovery process.
58 * <p>
59 * @param remoteCache
60 */
61 public void notifyError( RemoteHttpCache<?, ?> remoteCache )
62 {
63 if ( log.isInfoEnabled() )
64 {
65 log.info( "Notified of an error. " + remoteCache );
66 }
67
68 remoteHttpCaches.put( remoteCache, remoteCache );
69 notifyError();
70 }
71
72 /**
73 * Clean up all resources before shutdown
74 */
75 @Override
76 protected void dispose()
77 {
78 this.remoteHttpCaches.clear();
79 }
80
81 // Avoid the use of any synchronization in the process of monitoring for
82 // performance reasons.
83 // If exception is thrown owing to synchronization,
84 // just skip the monitoring until the next round.
85 /** Main processing method for the RemoteHttpCacheMonitor object */
86 @Override
87 protected void doWork()
88 {
89 // If no factory has been set, skip
90 if (factory == null)
91 {
92 return;
93 }
94
95 // If any cache is in error, it strongly suggests all caches
96 // managed by the same RmicCacheManager instance are in error. So we fix
97 // them once and for all.
98 for (RemoteHttpCache<?, ?> remoteCache : this.remoteHttpCaches.values())
99 {
100 try
101 {
102 if ( remoteCache.getStatus() == CacheStatus.ERROR )
103 {
104 RemoteHttpCacheAttributes attributes = remoteCache.getRemoteHttpCacheAttributes();
105
106 IRemoteHttpCacheClient<Serializable, Serializable> remoteService =
107 factory.createRemoteHttpCacheClientForAttributes( attributes );
108
109 if ( log.isInfoEnabled() )
110 {
111 log.info( "Performing Alive check on service " + remoteService );
112 }
113 // If we can't fix them, just skip and re-try in
114 // the next round.
115 if ( remoteService.isAlive() )
116 {
117 remoteCache.fixCache( remoteService );
118 }
119 else
120 {
121 allright.set(false);
122 }
123 break;
124 }
125 }
126 catch ( IOException ex )
127 {
128 allright.set(false);
129 // Problem encountered in fixing the caches managed by a
130 // RemoteCacheManager instance.
131 // Soldier on to the next RemoteHttpCache.
132 log.error( ex );
133 }
134 }
135 }
136 }