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 MemcachePortalCache<V> implements PortalCache<String, V> {
036
037 public MemcachePortalCache(
038 String name, MemcachedClientIF memcachedClient, int timeout,
039 TimeUnit timeoutTimeUnit) {
040
041 _name = name;
042 _memcachedClient = memcachedClient;
043 _timeout = timeout;
044 _timeoutTimeUnit = timeoutTimeUnit;
045 }
046
047 @Override
048 public void destroy() {
049 _memcachedClient.shutdown();
050 }
051
052 @Override
053 public Collection<V> get(Collection<String> keys) {
054 List<String> processedKeys = new ArrayList<String>(keys.size());
055
056 for (String key : keys) {
057 String processedKey = _name.concat(key);
058
059 processedKeys.add(processedKey);
060 }
061
062 Future<Map<String, Object>> future = null;
063
064 try {
065 future = _memcachedClient.asyncGetBulk(processedKeys);
066 }
067 catch (IllegalArgumentException iae) {
068 if (_log.isWarnEnabled()) {
069 _log.warn("Error retrieving with keys " + keys, iae);
070 }
071
072 return null;
073 }
074
075 Map<String, Object> values = null;
076
077 try {
078 values = future.get(_timeout, _timeoutTimeUnit);
079 }
080 catch (Throwable t) {
081 if (_log.isWarnEnabled()) {
082 _log.warn("Memcache operation error", t);
083 }
084
085 future.cancel(true);
086 }
087
088 if (values != null) {
089 return (Collection<V>)values.values();
090 }
091
092 return null;
093 }
094
095 @Override
096 public V get(String key) {
097 String processedKey = _name.concat(key);
098
099 Future<Object> future = null;
100
101 try {
102 future = _memcachedClient.asyncGet(processedKey);
103 }
104 catch (IllegalArgumentException iae) {
105 if (_log.isWarnEnabled()) {
106 _log.warn("Error retrieving with key " + key, iae);
107 }
108
109 return null;
110 }
111
112 Object value = null;
113
114 try {
115 value = future.get(_timeout, _timeoutTimeUnit);
116 }
117 catch (Throwable t) {
118 if (_log.isWarnEnabled()) {
119 _log.warn("Memcache operation error", t);
120 }
121
122 future.cancel(true);
123 }
124
125 return (V)value;
126 }
127
128 @Override
129 public List<String> getKeys() {
130 throw new UnsupportedOperationException();
131 }
132
133 @Override
134 public String getName() {
135 return _name;
136 }
137
138 @Override
139 public void put(String key, V value) {
140 put(key, value, _timeToLive);
141 }
142
143 @Override
144 public void put(String key, V value, int timeToLive) {
145 String processedKey = _name.concat(key);
146
147 try {
148 _memcachedClient.set(processedKey, timeToLive, value);
149 }
150 catch (IllegalArgumentException iae) {
151 if (_log.isWarnEnabled()) {
152 _log.warn("Error storing value with key " + key, iae);
153 }
154 }
155 }
156
157 @Override
158 public void registerCacheListener(CacheListener<String, V> cacheListener) {
159 registerCacheListener(cacheListener, CacheListenerScope.ALL);
160 }
161
162 @Override
163 public void registerCacheListener(
164 CacheListener<String, V> cacheListener,
165 CacheListenerScope cacheListenerScope) {
166
167 throw new UnsupportedOperationException();
168 }
169
170 @Override
171 public void remove(String key) {
172 String processedKey = _name.concat(key);
173
174 try {
175 _memcachedClient.delete(processedKey);
176 }
177 catch (IllegalArgumentException iae) {
178 if (_log.isWarnEnabled()) {
179 _log.warn("Error removing value with key " + key, iae);
180 }
181 }
182 }
183
184 @Override
185 public void removeAll() {
186 _memcachedClient.flush();
187 }
188
189 public void setTimeToLive(int timeToLive) {
190 _timeToLive = timeToLive;
191 }
192
193 @Override
194 public void unregisterCacheListener(
195 CacheListener<String, V> cacheListener) {
196 }
197
198 @Override
199 public void unregisterCacheListeners() {
200 }
201
202 private static Log _log = LogFactoryUtil.getLog(MemcachePortalCache.class);
203
204 private MemcachedClientIF _memcachedClient;
205 private String _name;
206 private int _timeout;
207 private TimeUnit _timeoutTimeUnit;
208 private int _timeToLive;
209
210 }