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