View Javadoc
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 }