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