| package org.apache.commons.jcs3.auxiliary.remote.http.client; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import java.io.IOException; |
| import java.io.Serializable; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import org.apache.commons.jcs3.auxiliary.AbstractAuxiliaryCacheMonitor; |
| import org.apache.commons.jcs3.auxiliary.remote.http.client.behavior.IRemoteHttpCacheClient; |
| import org.apache.commons.jcs3.engine.CacheStatus; |
| |
| /** |
| * Upon the notification of a connection error, the monitor changes to operate in a time driven |
| * mode. That is, it attempts to recover the connections on a periodic basis. When all failed |
| * connections are restored, it changes back to the failure driven mode. |
| */ |
| public class RemoteHttpCacheMonitor extends AbstractAuxiliaryCacheMonitor |
| { |
| /** Set of remote caches to monitor. This are added on error, if not before. */ |
| private final ConcurrentHashMap<RemoteHttpCache<?, ?>, RemoteHttpCache<?, ?>> remoteHttpCaches; |
| |
| /** Factory instance */ |
| private RemoteHttpCacheFactory factory = null; |
| |
| /** |
| * Constructor for the RemoteCacheMonitor object |
| * |
| * @param factory the factory to set |
| */ |
| public RemoteHttpCacheMonitor(final RemoteHttpCacheFactory factory) |
| { |
| super("JCS-RemoteHttpCacheMonitor"); |
| this.factory = factory; |
| this.remoteHttpCaches = new ConcurrentHashMap<>(); |
| setIdlePeriod(3000L); |
| } |
| |
| /** |
| * Notifies the cache monitor that an error occurred, and kicks off the error recovery process. |
| * <p> |
| * @param remoteCache |
| */ |
| public void notifyError( final RemoteHttpCache<?, ?> remoteCache ) |
| { |
| if ( log.isInfoEnabled() ) |
| { |
| log.info( "Notified of an error. " + remoteCache ); |
| } |
| |
| remoteHttpCaches.put( remoteCache, remoteCache ); |
| notifyError(); |
| } |
| |
| /** |
| * Clean up all resources before shutdown |
| */ |
| @Override |
| protected void dispose() |
| { |
| this.remoteHttpCaches.clear(); |
| } |
| |
| // Avoid the use of any synchronization in the process of monitoring for |
| // performance reasons. |
| // If exception is thrown owing to synchronization, |
| // just skip the monitoring until the next round. |
| /** Main processing method for the RemoteHttpCacheMonitor object */ |
| @Override |
| protected void doWork() |
| { |
| // If no factory has been set, skip |
| if (factory == null) |
| { |
| return; |
| } |
| |
| // If any cache is in error, it strongly suggests all caches |
| // managed by the same RmicCacheManager instance are in error. So we fix |
| // them once and for all. |
| for (final RemoteHttpCache<?, ?> remoteCache : this.remoteHttpCaches.values()) |
| { |
| try |
| { |
| if ( remoteCache.getStatus() == CacheStatus.ERROR ) |
| { |
| final RemoteHttpCacheAttributes attributes = remoteCache.getRemoteHttpCacheAttributes(); |
| |
| final IRemoteHttpCacheClient<Serializable, Serializable> remoteService = |
| factory.createRemoteHttpCacheClientForAttributes( attributes ); |
| |
| if ( log.isInfoEnabled() ) |
| { |
| log.info( "Performing Alive check on service " + remoteService ); |
| } |
| // If we can't fix them, just skip and re-try in |
| // the next round. |
| if ( remoteService.isAlive() ) |
| { |
| remoteCache.fixCache( remoteService ); |
| } |
| else |
| { |
| allright.set(false); |
| } |
| break; |
| } |
| } |
| catch ( final IOException ex ) |
| { |
| allright.set(false); |
| // Problem encountered in fixing the caches managed by a |
| // RemoteCacheManager instance. |
| // Soldier on to the next RemoteHttpCache. |
| log.error( ex ); |
| } |
| } |
| } |
| } |