You are viewing a plain text version of this content. The canonical link for it is here.
Posted to olio-commits@incubator.apache.org by te...@apache.org on 2009/09/30 14:04:16 UTC
svn commit: r820272 - in /incubator/olio/webapp/java/trunk/ws/apps/webapp:
./ src/java/org/apache/olio/webapp/cache/
src/java/org/apache/olio/webapp/controller/
src/java/org/apache/olio/webapp/model/ src/java/org/apache/olio/webapp/util/
Author: tekgrrl
Date: Wed Sep 30 14:04:15 2009
New Revision: 820272
URL: http://svn.apache.org/viewvc?rev=820272&view=rev
Log:
OLIO-95 put memcached layer back in Java app
Modified:
incubator/olio/webapp/java/trunk/ws/apps/webapp/build.xml
incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/Cache.java
incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/CacheFactory.java
incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/MemCachedFactory.java
incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/SimpleMapCacheFactory.java
incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/controller/EventAction.java
incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/model/ModelFacade.java
incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/util/ContentCachingFilter.java
incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/util/WebappUtil.java
Modified: incubator/olio/webapp/java/trunk/ws/apps/webapp/build.xml
URL: http://svn.apache.org/viewvc/incubator/olio/webapp/java/trunk/ws/apps/webapp/build.xml?rev=820272&r1=820271&r2=820272&view=diff
==============================================================================
--- incubator/olio/webapp/java/trunk/ws/apps/webapp/build.xml (original)
+++ incubator/olio/webapp/java/trunk/ws/apps/webapp/build.xml Wed Sep 30 14:04:15 2009
@@ -45,7 +45,7 @@
<fileset file="${webapp.lib}/rome-fetcher-0.9.jar"/>
<fileset file="${webapp.lib}/commons-fileupload-1.2.jar"/>
<fileset file="${webapp.lib}/commons-io-1.2.jar"/>
- <fileset file="${webapp.lib}/java_memcached-release_1.5.1.jar"/>
+ <fileset file="${webapp.lib}/java_memcached-release_2.0.1.jar"/>
<fileset file="${webapp.lib}/ajax-wrapper-comp-1.8.1.jar"/>
<fileset file="${webapp.lib}/JSON.jar"/>
<!-- add jersey files -->
Modified: incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/Cache.java
URL: http://svn.apache.org/viewvc/incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/Cache.java?rev=820272&r1=820271&r2=820272&view=diff
==============================================================================
--- incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/Cache.java (original)
+++ incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/Cache.java Wed Sep 30 14:04:15 2009
@@ -46,8 +46,21 @@
* @param timeToLive Time to cache this object in seconds
*/
void put(String key, Object value, long timeToLive);
-
- boolean needsRefresh (String key);
+
+ /**
+ * Invalidates a cached item using a key
+ * @param key
+ * @return success
+ */
+ boolean invalidate(String key);
+
+ /*
+ * Check if cache needs refresh based on existence cached object and of Semaphore
+ * @param key The key
+ * @param cacheObjPresent false if the cache object for this key exists
+ * @return true if the cache object needs a refresh
+ */
+ boolean needsRefresh (boolean cacheObjPresent, String key);
void doneRefresh (String key, long timeToNextRefresh) throws CacheException;
Modified: incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/CacheFactory.java
URL: http://svn.apache.org/viewvc/incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/CacheFactory.java?rev=820272&r1=820271&r2=820272&view=diff
==============================================================================
--- incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/CacheFactory.java (original)
+++ incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/CacheFactory.java Wed Sep 30 14:04:15 2009
@@ -171,7 +171,11 @@
public void put(String key, Object value, long timeToLive) {
}
- public boolean needsRefresh(String key) {
+ public boolean invalidate(String key) {
+ return false;
+ }
+
+ public boolean needsRefresh(boolean cachObjPresent, String cacheKey) {
return false;
}
Modified: incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/MemCachedFactory.java
URL: http://svn.apache.org/viewvc/incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/MemCachedFactory.java?rev=820272&r1=820271&r2=820272&view=diff
==============================================================================
--- incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/MemCachedFactory.java (original)
+++ incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/MemCachedFactory.java Wed Sep 30 14:04:15 2009
@@ -17,6 +17,7 @@
*/
package org.apache.olio.webapp.cache;
+import com.danga.MemCached.Logger;
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
import java.util.Date;
@@ -65,6 +66,7 @@
pool.initialize();
cache = new MemCachedClient();
+ MemCachedClient.getLogger().setLevel(Logger.LEVEL_WARN);
// Set thelog level to WARNING -- The defautl is INFO which causes unecessary logging
@@ -138,43 +140,48 @@
key + ", value=" + value + " to cache");
}
- public boolean needsRefresh(String key) {
- // Double checked lock. We first set the lock, then check whether we own the lock
- // If updateSema is not null, then we don't need to updatet he cache.
- // updateSema is stroed with a timeout, so it will expire based on
+ /** Invalidates a cached item using a key
+ *
+ * @param key The key
+ * @return success
+ */
+ public boolean invalidate(String key) {
+ // Only remove the Semaphore
+ return cache.delete(prefix + key + ".UpdateSema");
+ }
+
+ /*
+ * Check if cache needs refresh based on existence cached object and of Semaphore
+ * @param key The key
+ * @param cacheObjPresent false if the cache object for this key exists
+ * @return true if the object needs a refresh and if we have the lock
+ */
+ public boolean needsRefresh(boolean cacheObjPresent, String key) {
+ // Was a double checked lock. First set the lock, then check we own the lock
+ // Now using memcached's add which is an atomic get/set
+ // If updateSema is not null, then we don't need to update the cache.
+ // updateSema is stored with a timeout, so it will expire based on
// cache expiry time
String updateSema = prefix + key + ".UpdateSema";
String updateLock = prefix + key + ".UpdateLock";
- if (cache.get(updateSema) == null) {
+ if (!cacheObjPresent || cache.get(updateSema) == null) {
+ // the lockId is based on the threadId
String lockId = CacheFactory.getInstance().getLockId();
- if (cache.get(updateLock) == null) {
- Date expiryTime = new Date (System.currentTimeMillis()
+
+ Date expiryTime = new Date (System.currentTimeMillis()
+ CacheFactory.getInstance().getCacheLockExpireInSeconds()*1000);
-
- //if (!cache.set(updateLock, lockId, expiryTime)) {
- if (!cache.set(updateLock, lockId, expiryTime)) {
- throw new CacheException("Error setting updateLock - key = " +
- updateLock +" lockId = " + lockId);
- }
- else {
- System.out.println ("Set updateLock = " + updateLock +
- " with lockID = " + lockId);
- }
-
- // Now that we have set the lock. Check whether anyone has overwritten it.
- if (cache.get(updateLock) != null) {
- if (cache.get(updateLock).equals(lockId))
- return true;
- }
- else {
- System.out.println ("Get updateLock = " + updateLock +
- " return null" );
- throw new CacheException("Error getting updateLock - key = " +
- updateLock + " lockId = " + lockId);
-
- }
+
+ // Memcached's add is an atomic get/set and can be used for locking
+ if (!cache.add(updateLock, lockId, expiryTime)) {
+ // someone else has the lock, hopefully they are doing
+ // what we are trying to do
+ return false;
}
+ else
+ // we got the lock
+ return true;
}
+ // no refresh required
return false;
}
Modified: incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/SimpleMapCacheFactory.java
URL: http://svn.apache.org/viewvc/incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/SimpleMapCacheFactory.java?rev=820272&r1=820271&r2=820272&view=diff
==============================================================================
--- incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/SimpleMapCacheFactory.java (original)
+++ incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/cache/SimpleMapCacheFactory.java Wed Sep 30 14:04:15 2009
@@ -28,6 +28,8 @@
*/
public class SimpleMapCacheFactory extends CacheFactory {
+ private int cacheExpireInSeconds = 120; // in seconds
+
private static final ConcurrentHashMap<String,SoftReference<Object>> CACHE =
new ConcurrentHashMap<String, SoftReference<Object>>();
@@ -36,10 +38,16 @@
* @return The cache instance
* @param type
*/
+ @Override
public Cache createCache(String type) {
return new MapCache(type);
}
+ @Override
+ public int getCacheExpireInSeconds() {
+ return cacheExpireInSeconds;
+ }
+
static class MapCache implements Cache {
private String prefix;
@@ -87,16 +95,26 @@
}
}
- // This is not implemented for now.
- public boolean needsRefresh(String key) {
+ public boolean needsRefresh(boolean cacheObjPresent, String key) {
+ if (!cacheObjPresent || (expiryTime > 0 && System.currentTimeMillis() > expiryTime))
+ return true;
+
return false;
}
public void doneRefresh(String key, long timeToNextRefresh) throws CacheException {
+ // no-op
}
public boolean isLocal() {
return true;
}
+
+ public boolean invalidate(String key) {
+ put(key, null);
+ if (expiryTime == -1)
+ return true; // well we live in hope right?
+ return false;
+ }
}
}
Modified: incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/controller/EventAction.java
URL: http://svn.apache.org/viewvc/incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/controller/EventAction.java?rev=820272&r1=820271&r2=820272&view=diff
==============================================================================
--- incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/controller/EventAction.java (original)
+++ incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/controller/EventAction.java Wed Sep 30 14:04:15 2009
@@ -35,6 +35,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.olio.webapp.cache.CacheFactory;
/**
* Handles action for the event - update of comments and ratings.
@@ -69,17 +70,17 @@
if (path.equals("/detail")) {
SocialEvent se = mf.getSocialEvent(eid);
if (se == null)
- throw new RuntimeException("Could not find event. eventID = " + eid);
-
+ throw new RuntimeException("Could not find event. eventID = " + eid);
+
request.setAttribute("socialEvent", se);
boolean attending = false;
- Person user=SecurityHandler.getInstance().getLoggedInPerson(request);
-
- if (user != null)
+ Person user = SecurityHandler.getInstance().getLoggedInPerson(request);
+
+ if (user != null)
attending = se.isAttending(user);
-
+
request.setAttribute("isAttending", attending);
-
+
// If the user is looged in get the comment if there is any
if (user != null) {
CommentsRating cr = mf.getCommentRating(user, se);
@@ -91,15 +92,15 @@
}
if (path.equals("/delete"))
return deleteEvent(eid, request, response);
-
+
Person person=SecurityHandler.getInstance().getLoggedInPerson(request);
String comments = request.getParameter("comments");
-
+
SocialEvent event = mf.updateSocialEventComment(person, eid, comments, 0);
-
+
return "/site.jsp?page=event.jsp&socialEventID=" + eventID;
- }
-
+ }
+
private String deleteEvent (int eid, HttpServletRequest request, HttpServletResponse response) throws IOException {
ModelFacade mf= (ModelFacade) context.getAttribute(MF_KEY);
mf.deleteEvent(eid);
@@ -108,7 +109,7 @@
response.sendRedirect(request.getContextPath() + "/event/list");
return null;
}
-
+
private String addEvent (HttpServletRequest request, HttpServletResponse response) throws IOException {
String eventID = request.getParameter("socialEventID");
Person person=SecurityHandler.getInstance().getLoggedInPerson(request);
@@ -206,56 +207,84 @@
if (cache != null) {
String cacheKey = WebappUtil.getCacheKey("/event/list", queryMap);
if (cacheKey != null) {
- if (cache.isLocal()) {
- Object cobj = null;
- CachedList cl = (CachedList) cache.get(cacheKey);
- if (cl == null) {
- cl = new CachedList(cacheKey);
- cache.put(cacheKey, cl, WebappUtil.getCacheTimeToLiveInSecs());
- }
- cobj = cl.get(index);
- if (cobj== null) {
- // Fill the cache
- List<SocialEvent> list = mf.getSocialEvents(queryMap);
- int numPages = 1;
- if (list != null) {
- Object o = queryMap.get("listSize");
- if (o != null) {
- Long l = (Long) o;
- numPages = WebappUtil.getNumPages(l);
- }
- }
-
- request.setAttribute("itemList", list);
- request.setAttribute("numPages", numPages);
- cobj = WebappUtil.acquirePageContent("/eventList.jsp", request, response);
- cl.put(index, cobj);
- //System.out.println ("Put content in cache - key = " + cacheKey +
- // " index = " + index);
- }
- else {
- //System.out.println ("Got content from cache - key = " + cacheKey +
- // " index = " + index);
+
+ Object cobj = null;
+
+ CachedList cl = (CachedList)cache.get(cacheKey);
+
+ if (cl == null) {
+ // nothing in cache
+ cl = new CachedList(cacheKey);
+
+ // get a new cacheable page/partial
+ cobj = createCachePageObject(queryMap, response, request, mf);
+ cl.put(index, cobj);
+
+
+ if (cache.needsRefresh(false, cacheKey)) {
+ cache.put(cacheKey, cl, CacheFactory.getInstance().getCacheExpireInSeconds());
+ cache.doneRefresh(cacheKey, CacheFactory.getInstance().getCacheLockExpireInSeconds());
}
- if (cobj != null) {
- request.setAttribute("content", cobj);
- if (pageType != null && pageType.equalsIgnoreCase("partial")) {
- response.getWriter().print((String) cobj);
- return null;
- }
- else {
- return "/site.jsp?cachedContent=true";
- }
+
+ } else {
+ // something in the cache
+ cobj = cl.get(index); // we are using this whatever
+
+ Object newCobj = createCachePageObject(queryMap, response, request, mf);
+ cl.put(index, newCobj); // replaces existing value
+ if (cache.needsRefresh(true, cacheKey)) {
+ cache.put(cacheKey, cl, CacheFactory.getInstance().getCacheExpireInSeconds());
+ cache.doneRefresh(cacheKey, CacheFactory.getInstance().getCacheLockExpireInSeconds());
}
}
- else {
- // TO DO -- Needs different logic for distributed caches since we
- // don't intent to cache heirarchical objects in that mode.
+
+ if (cobj != null) {
+ request.setAttribute("content", cobj);
+
+ // if it's a partial page then we can just write cobj to the response stream
+ // But we don't cache partials at the moment
+ if (pageType != null && pageType.equalsIgnoreCase("partial")) {
+ response.getWriter().print((String) cobj);
+ return null;
+ } else {
+ // if it's not a partial, we'll redirect and tell it that there's cached content to display
+ return "/site.jsp?cachedContent=true";
+ }
}
}
}
- // This is not cacheable or cache is not enabled.
+ return prepNoCacheRequest(queryMap, response, request, mf);
+
+ }
+
+ private Object createCachePageObject(Map<String, Object> queryMap,
+ HttpServletResponse response,
+ HttpServletRequest request,
+ ModelFacade mf) throws java.io.IOException,
+ javax.servlet.ServletException {
+
+ // Fill the cache
+ List<SocialEvent> list = mf.getSocialEvents(queryMap);
+ int numPages = 1;
+ if (list != null) {
+ Object o = queryMap.get("listSize");
+ if (o != null) {
+ Long l = (Long) o;
+ numPages = WebappUtil.getNumPages(l);
+ }
+ }
+
+ request.setAttribute("itemList", list);
+ request.setAttribute("numPages", numPages);
+
+ return WebappUtil.acquirePageContent("/eventList.jsp", request, response);
+ }
+
+ private String prepNoCacheRequest(Map<String, Object> queryMap, HttpServletResponse response, HttpServletRequest request, ModelFacade mf) {
+
+ String pageType = request.getParameter("displayType");
+ int index = WebappUtil.getIntProperty(request.getParameter("index"));
List<SocialEvent> list = mf.getSocialEvents(queryMap);
int numPages = 1;
@@ -305,19 +334,20 @@
return "/site.jsp?page=eventList.jsp&index="+index;
}
- static class CachedList {
+ static class CachedList implements java.io.Serializable {
+
public String cacheKey;
public HashMap<Integer, Object> valueMap;
-
- public CachedList (String key) {
+
+ public CachedList(String key) {
this.cacheKey = key;
valueMap = new HashMap<Integer, Object>();
}
-
+
public void put(int index, Object value) {
valueMap.put(index, value);
}
-
+
public Object get(int index) {
return valueMap.get(index);
}
Modified: incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/model/ModelFacade.java
URL: http://svn.apache.org/viewvc/incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/model/ModelFacade.java?rev=820272&r1=820271&r2=820272&view=diff
==============================================================================
--- incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/model/ModelFacade.java (original)
+++ incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/model/ModelFacade.java Wed Sep 30 14:04:15 2009
@@ -78,10 +78,7 @@
/** Creates a new instance of ModelFacade */
public ModelFacade() {
calendar = GregorianCalendar.getInstance();
- // Default the jMaki usage to true
- ServiceLocator sloc = ServiceLocator.getInstance();
- jmakiUsage = Boolean.parseBoolean(sloc.getString("webapp.jmakiUsage", "true"));
- useCache = Boolean.parseBoolean(sloc.getString("useLocalCache", "true"));
+
/*
try {
FileSystem fs = ServiceLocator.getInstance().getFileSystem();
@@ -107,6 +104,10 @@
context = sce.getServletContext();
getContext().setAttribute(WebConstants.MF_KEY, this);
WebappUtil.setContext(getContext().getContextPath());
+
+ ServiceLocator sloc = ServiceLocator.getInstance();
+ jmakiUsage = Boolean.parseBoolean(sloc.getString("webapp.jmakiUsage", "false"));
+ useCache = Boolean.parseBoolean(sloc.getString("useLocalCache", "true"));
}
//public String addPerson(Person person, UserSignOn userSignOn){
Modified: incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/util/ContentCachingFilter.java
URL: http://svn.apache.org/viewvc/incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/util/ContentCachingFilter.java?rev=820272&r1=820271&r2=820272&view=diff
==============================================================================
--- incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/util/ContentCachingFilter.java (original)
+++ incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/util/ContentCachingFilter.java Wed Sep 30 14:04:15 2009
@@ -157,7 +157,7 @@
if (obj != null) {
// The page is cached. But does it need a refresh?
- if (cache.needsRefresh(key)) {
+ if (cache.needsRefresh(true, key)) {
// We own the lock, so we need to refresh it
String str = acquirePageContent (path, request, response, chain);
if (str != null) {
@@ -189,7 +189,7 @@
int attemptCount = 1;
while (true) {
System.out.println ("needsRefreshAttempt = " + attemptCount++);
- if (cache.needsRefresh(key)) {
+ if (cache.needsRefresh(false, key)) {
// We have the lock, refresh the content
String str = acquirePageContent (path, request, response, chain);
if (str != null) {
Modified: incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/util/WebappUtil.java
URL: http://svn.apache.org/viewvc/incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/util/WebappUtil.java?rev=820272&r1=820271&r2=820272&view=diff
==============================================================================
--- incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/util/WebappUtil.java (original)
+++ incubator/olio/webapp/java/trunk/ws/apps/webapp/src/java/org/apache/olio/webapp/util/WebappUtil.java Wed Sep 30 14:04:15 2009
@@ -86,9 +86,7 @@
monthMap.put("nov", 11);
monthMap.put("dec", 12);
- String useCache = ServiceLocator.getInstance().getString("useLocalCache", "true");
- if (Boolean.parseBoolean(useCache))
- cache = CacheFactory.getCache("Olio");
+ cache = CacheFactory.getCache("Olio");
}
/** Creates a new instance of WebappUtil */
@@ -539,7 +537,8 @@
return;
String key = getCacheKey(path, map);
if (key != null) {
- cache.put(key, null);
+ System.out.println("WebappUtil.clearCache(): " + key);
+ cache.invalidate(key);
}
}