001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.cache.memcached;
016    
017    import com.liferay.portal.kernel.cache.BasePortalCache;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    
021    import java.io.Serializable;
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    /**
033     * @author Michael C. Han
034     */
035    public class PooledMemcachePortalCache extends BasePortalCache {
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<Object> 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 = processKey(_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 values.values();
105            }
106    
107            public Object 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 = processKey(_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 value;
141                    }
142                    finally {
143                            cleanupClient(memcachedClient);
144                    }
145            }
146    
147            public void put(String key, Object obj) {
148                    put(key, obj, _timeToLive);
149            }
150    
151            public void put(String key, Object obj, int timeToLive) {
152                    MemcachedClientIF memcachedClient = null;
153    
154                    try {
155                            memcachedClient = _memcachedClientFactory.getMemcachedClient();
156                    }
157                    catch (Exception e) {
158                            return;
159                    }
160    
161                    String processedKey = processKey(_name.concat(key));
162    
163                    try {
164                            memcachedClient.set(processedKey, timeToLive, obj);
165                    }
166                    catch (IllegalArgumentException iae) {
167                            if (_log.isWarnEnabled()) {
168                                    _log.warn("Error storing value with key " + key, iae);
169                            }
170                    }
171                    finally {
172                            cleanupClient(memcachedClient);
173                    }
174            }
175    
176            public void put(String key, Serializable obj) {
177                    put(key, obj, _timeToLive);
178            }
179    
180            public void put(String key, Serializable obj, int timeToLive) {
181                    MemcachedClientIF memcachedClient = null;
182    
183                    try {
184                            memcachedClient = _memcachedClientFactory.getMemcachedClient();
185                    }
186                    catch (Exception e) {
187                            return;
188                    }
189    
190                    String processedKey = processKey(_name.concat(key));
191    
192                    try {
193                            memcachedClient.set(processedKey, timeToLive, obj);
194                    }
195                    catch (IllegalArgumentException iae) {
196                            if (_log.isWarnEnabled()) {
197                                    _log.warn("Error storing value with key " + key, iae);
198                            }
199                    }
200                    finally {
201                            cleanupClient(memcachedClient);
202                    }
203            }
204    
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 = processKey(_name.concat(key));
216    
217                    try {
218                            memcachedClient.delete(processedKey);
219                    }
220                    catch (IllegalArgumentException iae) {
221                            if (_log.isWarnEnabled()) {
222                                    _log.warn("Error deleting value with key " + key, iae);
223                            }
224                    }
225                    finally {
226                            cleanupClient(memcachedClient);
227                    }
228            }
229    
230            public void removeAll() {
231                    MemcachedClientIF memcachedClient = null;
232    
233                    try {
234                            memcachedClient = _memcachedClientFactory.getMemcachedClient();
235                    }
236                    catch (Exception e) {
237                            return;
238                    }
239    
240                    try {
241                            memcachedClient.flush();
242                    }
243                    finally {
244                            cleanupClient(memcachedClient);
245                    }
246            }
247    
248            public void setTimeToLive(int timeToLive) {
249                    _timeToLive = timeToLive;
250            }
251    
252            protected void cleanupClient(MemcachedClientIF memcachedClient) {
253                    try {
254                            _memcachedClientFactory.returnMemcachedObject(memcachedClient);
255                    }
256                    catch (Exception e) {
257                    }
258            }
259    
260            private static final Log _log = LogFactoryUtil.getLog(
261                    MemcachePortalCache.class);
262    
263            private MemcachedClientFactory _memcachedClientFactory;
264            private String _name;
265            private int _timeout;
266            private TimeUnit _timeoutTimeUnit;
267            private int _timeToLive;
268    
269    }