001
014
015 package com.liferay.portal.cache.memcached;
016
017 import com.liferay.portal.kernel.cache.CacheListener;
018 import com.liferay.portal.kernel.cache.CacheListenerScope;
019 import com.liferay.portal.kernel.cache.PortalCache;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022
023 import java.io.Serializable;
024
025 import java.util.ArrayList;
026 import java.util.Collection;
027 import java.util.List;
028 import java.util.Map;
029 import java.util.concurrent.Future;
030 import java.util.concurrent.TimeUnit;
031
032 import net.spy.memcached.MemcachedClientIF;
033
034
037 public class PooledMemcachePortalCache implements PortalCache {
038
039 public PooledMemcachePortalCache(
040 String name, MemcachedClientFactory memcachedClientFactory, int timeout,
041 TimeUnit timeoutTimeUnit) {
042
043 _name = name;
044 _memcachedClientFactory = memcachedClientFactory;
045 _timeout = timeout;
046 _timeoutTimeUnit = timeoutTimeUnit;
047 }
048
049 @Override
050 public void destroy() {
051 try {
052 _memcachedClientFactory.close();
053 }
054 catch (Exception e) {
055 }
056 }
057
058 @Override
059 public Collection<Object> get(Collection<Serializable> keys) {
060 MemcachedClientIF memcachedClient = null;
061
062 try {
063 memcachedClient = _memcachedClientFactory.getMemcachedClient();
064 }
065 catch (Exception e) {
066 return null;
067 }
068
069 List<String> processedKeys = new ArrayList<String>(keys.size());
070
071 for (Serializable key : keys) {
072 String processedKey = _name.concat(String.valueOf(key));
073
074 processedKeys.add(processedKey);
075 }
076
077 Map<String, Object> values = null;
078
079 try {
080 Future<Map<String, Object>> future = null;
081
082 try {
083 future = memcachedClient.asyncGetBulk(processedKeys);
084 }
085 catch (IllegalArgumentException iae) {
086 if (_log.isWarnEnabled()) {
087 _log.warn("Error retrieving with keys " + keys, iae);
088 }
089
090 future.cancel(true);
091 }
092
093 try {
094 values = future.get(_timeout, _timeoutTimeUnit);
095 }
096 catch (Throwable t) {
097 if (_log.isWarnEnabled()) {
098 _log.warn("Memcache operation error", t);
099 }
100
101 future.cancel(true);
102 }
103 }
104 finally {
105 cleanupClient(memcachedClient);
106 }
107
108 return values.values();
109 }
110
111 @Override
112 public Object get(Serializable key) {
113 MemcachedClientIF memcachedClient = null;
114
115 try {
116 memcachedClient = _memcachedClientFactory.getMemcachedClient();
117 }
118 catch (Exception e) {
119 return null;
120 }
121
122 String processedKey = _name.concat(String.valueOf(key));
123
124 try {
125 Future<Object> future = null;
126
127 try {
128 future = memcachedClient.asyncGet(processedKey);
129 }
130 catch (IllegalArgumentException iae) {
131 if (_log.isWarnEnabled()) {
132 _log.warn("Error retrieving with key " + key, iae);
133 }
134 }
135
136 Object value = null;
137
138 try {
139 value = future.get(_timeout, _timeoutTimeUnit);
140 }
141 catch (Exception e) {
142 future.cancel(true);
143 }
144
145 return value;
146 }
147 finally {
148 cleanupClient(memcachedClient);
149 }
150 }
151
152 @Override
153 public String getName() {
154 return _name;
155 }
156
157 @Override
158 public void put(Serializable key, Object value) {
159 put(key, value, _timeToLive);
160 }
161
162 @Override
163 public void put(Serializable key, Object value, int timeToLive) {
164 MemcachedClientIF memcachedClient = null;
165
166 try {
167 memcachedClient = _memcachedClientFactory.getMemcachedClient();
168 }
169 catch (Exception e) {
170 return;
171 }
172
173 String processedKey = _name.concat(String.valueOf(key));
174
175 try {
176 memcachedClient.set(processedKey, timeToLive, value);
177 }
178 catch (IllegalArgumentException iae) {
179 if (_log.isWarnEnabled()) {
180 _log.warn("Error storing value with key " + key, iae);
181 }
182 }
183 finally {
184 cleanupClient(memcachedClient);
185 }
186 }
187
188 @Override
189 public void put(Serializable key, Serializable value) {
190 put(key, value, _timeToLive);
191 }
192
193 @Override
194 public void put(Serializable key, Serializable value, int timeToLive) {
195 MemcachedClientIF memcachedClient = null;
196
197 try {
198 memcachedClient = _memcachedClientFactory.getMemcachedClient();
199 }
200 catch (Exception e) {
201 return;
202 }
203
204 String processedKey = _name.concat(String.valueOf(key));
205
206 try {
207 memcachedClient.set(processedKey, timeToLive, value);
208 }
209 catch (IllegalArgumentException iae) {
210 if (_log.isWarnEnabled()) {
211 _log.warn("Error storing value with key " + key, iae);
212 }
213 }
214 finally {
215 cleanupClient(memcachedClient);
216 }
217 }
218
219 @Override
220 public void registerCacheListener(CacheListener cacheListener) {
221 registerCacheListener(cacheListener, CacheListenerScope.ALL);
222 }
223
224 @Override
225 public void registerCacheListener(
226 CacheListener cacheListener, CacheListenerScope cacheListenerScope) {
227
228 throw new UnsupportedOperationException();
229 }
230
231 @Override
232 public void remove(Serializable key) {
233 MemcachedClientIF memcachedClient = null;
234
235 try {
236 memcachedClient = _memcachedClientFactory.getMemcachedClient();
237 }
238 catch (Exception e) {
239 return;
240 }
241
242 String processedKey = _name.concat(String.valueOf(key));
243
244 try {
245 memcachedClient.delete(processedKey);
246 }
247 catch (IllegalArgumentException iae) {
248 if (_log.isWarnEnabled()) {
249 _log.warn("Unable to delete value with key " + key, iae);
250 }
251 }
252 finally {
253 cleanupClient(memcachedClient);
254 }
255 }
256
257 @Override
258 public void removeAll() {
259 MemcachedClientIF memcachedClient = null;
260
261 try {
262 memcachedClient = _memcachedClientFactory.getMemcachedClient();
263 }
264 catch (Exception e) {
265 return;
266 }
267
268 try {
269 memcachedClient.flush();
270 }
271 finally {
272 cleanupClient(memcachedClient);
273 }
274 }
275
276 public void setTimeToLive(int timeToLive) {
277 _timeToLive = timeToLive;
278 }
279
280 @Override
281 public void unregisterCacheListener(CacheListener cacheListener) {
282 }
283
284 @Override
285 public void unregisterCacheListeners() {
286 }
287
288 protected void cleanupClient(MemcachedClientIF memcachedClient) {
289 try {
290 _memcachedClientFactory.returnMemcachedObject(memcachedClient);
291 }
292 catch (Exception e) {
293 }
294 }
295
296 private static Log _log = LogFactoryUtil.getLog(
297 PooledMemcachePortalCache.class);
298
299 private MemcachedClientFactory _memcachedClientFactory;
300 private String _name;
301 private int _timeout;
302 private TimeUnit _timeoutTimeUnit;
303 private int _timeToLive;
304
305 }