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