| %line | %branch | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| org.apache.jcs.auxiliary.remote.ZombieRemoteCacheService$PutEvent |
|
|
| 1 | package org.apache.jcs.auxiliary.remote; |
|
| 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.Collections; |
|
| 25 | import java.util.Set; |
|
| 26 | ||
| 27 | import org.apache.commons.logging.Log; |
|
| 28 | import org.apache.commons.logging.LogFactory; |
|
| 29 | import org.apache.jcs.auxiliary.remote.behavior.IRemoteCacheService; |
|
| 30 | import org.apache.jcs.engine.ZombieCacheService; |
|
| 31 | import org.apache.jcs.engine.behavior.ICacheElement; |
|
| 32 | import org.apache.jcs.utils.struct.BoundedQueue; |
|
| 33 | import org.apache.jcs.utils.timing.ElapsedTimer; |
|
| 34 | ||
| 35 | /** |
|
| 36 | * Zombie adapter for the remote cache service. It just balks if there is no queue configured. If a |
|
| 37 | * queue is configured, then events will be added to the queue. The idea is that when proper |
|
| 38 | * operation is restored, the remote cache will walk the queue. The queue must be bounded so it does |
|
| 39 | * not eat memory. |
|
| 40 | * <p> |
|
| 41 | * Much of this is potentially reusable. |
|
| 42 | * <p> |
|
| 43 | * TODO figure out a way to get the propagate method into an interface for Zombies. |
|
| 44 | */ |
|
| 45 | public class ZombieRemoteCacheService |
|
| 46 | extends ZombieCacheService |
|
| 47 | implements IRemoteCacheService |
|
| 48 | { |
|
| 49 | private final static Log log = LogFactory.getLog( ZombieRemoteCacheService.class ); |
|
| 50 | ||
| 51 | private int maxQueueSize = 0; |
|
| 52 | ||
| 53 | private BoundedQueue queue; |
|
| 54 | ||
| 55 | /** |
|
| 56 | * Default. |
|
| 57 | */ |
|
| 58 | public ZombieRemoteCacheService() |
|
| 59 | { |
|
| 60 | queue = new BoundedQueue( 0 ); |
|
| 61 | } |
|
| 62 | ||
| 63 | /** |
|
| 64 | * Sets the maximum number of items that will be allowed on the queue. |
|
| 65 | * <p> |
|
| 66 | * @param maxQueueSize |
|
| 67 | */ |
|
| 68 | public ZombieRemoteCacheService( int maxQueueSize ) |
|
| 69 | { |
|
| 70 | this.maxQueueSize = maxQueueSize; |
|
| 71 | queue = new BoundedQueue( maxQueueSize ); |
|
| 72 | } |
|
| 73 | ||
| 74 | /** |
|
| 75 | * Gets the number of items on the queue. |
|
| 76 | * <p> |
|
| 77 | * @return size of the queue. |
|
| 78 | */ |
|
| 79 | public int getQueueSize() |
|
| 80 | { |
|
| 81 | return queue.size(); |
|
| 82 | } |
|
| 83 | ||
| 84 | /** |
|
| 85 | * Adds an update event to the queue if the maxSize is greater than 0; |
|
| 86 | * <p> |
|
| 87 | * (non-Javadoc) |
|
| 88 | * @see org.apache.jcs.auxiliary.remote.behavior.IRemoteCacheService#update(org.apache.jcs.engine.behavior.ICacheElement, |
|
| 89 | * long) |
|
| 90 | */ |
|
| 91 | public void update( ICacheElement item, long listenerId ) |
|
| 92 | { |
|
| 93 | if ( maxQueueSize > 0 ) |
|
| 94 | { |
|
| 95 | PutEvent event = new PutEvent( item, listenerId ); |
|
| 96 | queue.add( event ); |
|
| 97 | } |
|
| 98 | // Zombies have no inner life |
|
| 99 | return; |
|
| 100 | } |
|
| 101 | ||
| 102 | /** |
|
| 103 | * Adds a removeAll event to the queue if the maxSize is greater than 0; |
|
| 104 | * <p> |
|
| 105 | * (non-Javadoc) |
|
| 106 | * @see org.apache.jcs.auxiliary.remote.behavior.IRemoteCacheService#remove(java.lang.String, |
|
| 107 | * java.io.Serializable, long) |
|
| 108 | */ |
|
| 109 | public void remove( String cacheName, Serializable key, long listenerId ) |
|
| 110 | { |
|
| 111 | if ( maxQueueSize > 0 ) |
|
| 112 | { |
|
| 113 | RemoveEvent event = new RemoveEvent( cacheName, key, listenerId ); |
|
| 114 | queue.add( event ); |
|
| 115 | } |
|
| 116 | // Zombies have no inner life |
|
| 117 | return; |
|
| 118 | } |
|
| 119 | ||
| 120 | /** |
|
| 121 | * Adds a removeAll event to the queue if the maxSize is greater than 0; |
|
| 122 | * <p> |
|
| 123 | * (non-Javadoc) |
|
| 124 | * @see org.apache.jcs.auxiliary.remote.behavior.IRemoteCacheService#removeAll(java.lang.String, |
|
| 125 | * long) |
|
| 126 | */ |
|
| 127 | public void removeAll( String cacheName, long listenerId ) |
|
| 128 | { |
|
| 129 | if ( maxQueueSize > 0 ) |
|
| 130 | { |
|
| 131 | RemoveAllEvent event = new RemoveAllEvent( cacheName, listenerId ); |
|
| 132 | queue.add( event ); |
|
| 133 | } |
|
| 134 | // Zombies have no inner life |
|
| 135 | return; |
|
| 136 | } |
|
| 137 | ||
| 138 | /** |
|
| 139 | * Does nothing. Gets are synchronous and cannot be added to a queue. |
|
| 140 | * <p> |
|
| 141 | * (non-Javadoc) |
|
| 142 | * @see org.apache.jcs.auxiliary.remote.behavior.IRemoteCacheService#get(java.lang.String, |
|
| 143 | * java.io.Serializable, long) |
|
| 144 | */ |
|
| 145 | public ICacheElement get( String cacheName, Serializable key, long requesterId ) |
|
| 146 | throws IOException |
|
| 147 | { |
|
| 148 | // Zombies have no inner life |
|
| 149 | return null; |
|
| 150 | } |
|
| 151 | ||
| 152 | /** |
|
| 153 | * Does nothing. |
|
| 154 | * <p> |
|
| 155 | * (non-Javadoc) |
|
| 156 | * @see org.apache.jcs.auxiliary.remote.behavior.IRemoteCacheService#getGroupKeys(java.lang.String, |
|
| 157 | * java.lang.String) |
|
| 158 | */ |
|
| 159 | public Set getGroupKeys( String cacheName, String groupName ) |
|
| 160 | { |
|
| 161 | return Collections.EMPTY_SET; |
|
| 162 | } |
|
| 163 | ||
| 164 | /** |
|
| 165 | * Walk the queue, calling the service for each queue operation. |
|
| 166 | * <p> |
|
| 167 | * @param service |
|
| 168 | * @throws Exception |
|
| 169 | */ |
|
| 170 | protected void propagateEvents( IRemoteCacheService service ) |
|
| 171 | throws Exception |
|
| 172 | { |
|
| 173 | int cnt = 0; |
|
| 174 | if ( log.isInfoEnabled() ) |
|
| 175 | { |
|
| 176 | log.info( "Propagating events to the new RemoteService." ); |
|
| 177 | } |
|
| 178 | ElapsedTimer timer = new ElapsedTimer(); |
|
| 179 | while ( !queue.isEmpty() ) |
|
| 180 | { |
|
| 181 | cnt++; |
|
| 182 | ||
| 183 | // for each item, call the appropriate service method |
|
| 184 | ZombieEvent event = (ZombieEvent) queue.take(); |
|
| 185 | ||
| 186 | if ( event instanceof PutEvent ) |
|
| 187 | { |
|
| 188 | PutEvent putEvent = (PutEvent) event; |
|
| 189 | service.update( putEvent.element, event.requesterId ); |
|
| 190 | } |
|
| 191 | else if ( event instanceof RemoveEvent ) |
|
| 192 | { |
|
| 193 | RemoveEvent removeEvent = (RemoveEvent) event; |
|
| 194 | service.remove( event.cacheName, removeEvent.key, event.requesterId ); |
|
| 195 | } |
|
| 196 | else if ( event instanceof RemoveAllEvent ) |
|
| 197 | { |
|
| 198 | service.removeAll( event.cacheName, event.requesterId ); |
|
| 199 | } |
|
| 200 | } |
|
| 201 | if ( log.isInfoEnabled() ) |
|
| 202 | { |
|
| 203 | log.info( "Propagated " + cnt + " events to the new RemoteService in " + timer.getElapsedTimeString() ); |
|
| 204 | } |
|
| 205 | } |
|
| 206 | ||
| 207 | /** |
|
| 208 | * Base of the other events. |
|
| 209 | */ |
|
| 210 | private abstract class ZombieEvent |
|
| 211 | { |
|
| 212 | String cacheName; |
|
| 213 | ||
| 214 | long requesterId; |
|
| 215 | } |
|
| 216 | ||
| 217 | /** |
|
| 218 | * A basic put event. |
|
| 219 | */ |
|
| 220 | private class PutEvent |
|
| 221 | extends ZombieEvent |
|
| 222 | { |
|
| 223 | ICacheElement element; |
|
| 224 | ||
| 225 | /** |
|
| 226 | * Set the element |
|
| 227 | * @param element |
|
| 228 | * @param requesterId |
|
| 229 | */ |
|
| 230 | public PutEvent( ICacheElement element, long requesterId ) |
|
| 231 | 14 | { |
| 232 | 14 | this.requesterId = requesterId; |
| 233 | 14 | this.element = element; |
| 234 | 14 | } |
| 235 | } |
|
| 236 | ||
| 237 | /** |
|
| 238 | * A basic Remove event. |
|
| 239 | */ |
|
| 240 | private class RemoveEvent |
|
| 241 | extends ZombieEvent |
|
| 242 | { |
|
| 243 | Serializable key; |
|
| 244 | ||
| 245 | /** |
|
| 246 | * Set the element |
|
| 247 | * @param cacheName |
|
| 248 | * @param key |
|
| 249 | * @param requesterId |
|
| 250 | */ |
|
| 251 | public RemoveEvent( String cacheName, Serializable key, long requesterId ) |
|
| 252 | { |
|
| 253 | this.cacheName = cacheName; |
|
| 254 | this.requesterId = requesterId; |
|
| 255 | this.key = key; |
|
| 256 | } |
|
| 257 | } |
|
| 258 | ||
| 259 | /** |
|
| 260 | * A basic RemoveAll event. |
|
| 261 | */ |
|
| 262 | private class RemoveAllEvent |
|
| 263 | extends ZombieEvent |
|
| 264 | { |
|
| 265 | /** |
|
| 266 | * @param cacheName |
|
| 267 | * @param requesterId |
|
| 268 | */ |
|
| 269 | public RemoveAllEvent( String cacheName, long requesterId ) |
|
| 270 | { |
|
| 271 | this.cacheName = cacheName; |
|
| 272 | this.requesterId = requesterId; |
|
| 273 | } |
|
| 274 | } |
|
| 275 | } |
| This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |