Author: cziegeler
Date: Tue Jun 30 12:53:14 2009
New Revision: 789698
URL: http://svn.apache.org/viewvc?rev=789698&view=rev
Log:
SLING-1027 : First implementation of a configurable cache for the script
resolution.
Modified:
sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
sling/trunk/bundles/servlets/resolver/src/main/resources/OSGI-INF/metatype/metatype.properties
Modified:
sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java?rev=789698&r1=789697&r2=789698&view=diff
==============================================================================
---
sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
(original)
+++
sling/trunk/bundles/servlets/resolver/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
Tue Jun 30 12:53:14 2009
@@ -32,6 +32,7 @@
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import javax.jcr.Credentials;
import javax.jcr.RepositoryException;
@@ -72,6 +73,8 @@
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -92,9 +95,11 @@
* @scr.service
* @scr.reference name="Servlet" interface="javax.servlet.Servlet"
* cardinality="0..n" policy="dynamic"
+ * @scr.property name="event.topics" value="org/apache/sling/api/resource/*"
+ * private="true"
*/
public class SlingServletResolver implements ServletResolver,
- SlingScriptResolver, ErrorHandler {
+ SlingScriptResolver, ErrorHandler, EventHandler {
/** default log */
private final Logger log = LoggerFactory.getLogger(getClass());
@@ -109,9 +114,17 @@
*/
public static final String PROP_SCRIPT_USER = "servletresolver.scriptUser";
+ /**
+ * @scr.property valueRef="DEFAULT_CACHE_SIZE"
+ */
+ public static final String PROP_CACHE_SIZE = "servletresolver.cacheSize";
+
/** The default servlet root is the first search path (which is usally
/apps) */
public static final String DEFAULT_SERVLET_ROOT = "0";
+ /** The default cache size for the script resolution. */
+ public static final Integer DEFAULT_CACHE_SIZE = 200;
+
private static final String REF_SERVLET = "Servlet";
/** @scr.reference */
@@ -146,6 +159,8 @@
// a request. This field is set on demand by getDefaultErrorServlet()
private Servlet defaultErrorServlet;
+ private Map<ResourceCollector, Servlet> cache;
+
// ---------- ServletResolver interface -----------------------------------
/**
@@ -427,6 +442,11 @@
*/
private Servlet getServlet(final ResourceCollector locationUtil,
final SlingHttpServletRequest request) {
+ final Servlet scriptServlet = (this.cache != null ?
this.cache.get(locationUtil) : null);
+ if ( scriptServlet != null ) {
+ return scriptServlet;
+ }
+
final Collection<Resource> candidates =
locationUtil.getServlets(this.scriptResolver);
if (log.isDebugEnabled()) {
@@ -440,6 +460,7 @@
}
}
+ boolean hasOptingServlet = false;
for (Resource candidateResource : candidates) {
if(log.isDebugEnabled()) {
log.debug("Checking if candidate resource {} adapts to
servlet and accepts request",
@@ -451,8 +472,14 @@
boolean servletAcceptsRequest = !isOptingServlet
|| ((OptingServlet) candidate).accepts(request);
if (servletAcceptsRequest) {
+ if ( !hasOptingServlet && !isOptingServlet && this.cache
!= null ) {
+ this.cache.put(locationUtil, candidate);
+ }
return candidate;
}
+ if ( isOptingServlet ) {
+ hasOptingServlet = true;
+ }
if(log.isDebugEnabled()) {
log.debug("Candidate {} does not accept request,
ignored", candidateResource.getPath());
}
@@ -579,6 +606,11 @@
}
+ // create cache - if a cache size is configured
+ final int cacheSize =
OsgiUtil.toInteger(properties.get(PROP_CACHE_SIZE), DEFAULT_CACHE_SIZE);
+ if ( cacheSize > 5 ) {
+ this.cache = new ConcurrentHashMap<ResourceCollector,
Servlet>(cacheSize);
+ }
createAllServlets(refs);
}
@@ -597,6 +629,7 @@
this.scriptSession = null;
}
this.context = null;
+ this.cache = null;
this.servletResourceProviderFactory = null;
}
@@ -717,4 +750,27 @@
}
}
}
+
+ /**
+ * @see
org.osgi.service.event.EventHandler#handleEvent(org.osgi.service.event.Event)
+ */
+ public void handleEvent(Event event) {
+ if ( this.cache != null ) {
+ // if the path of the event is a sub path of a search path
+ // we flush the whole cache
+ boolean flushCache = false;
+ final String path = (String)
event.getProperty(SlingConstants.PROPERTY_PATH);
+ final String[] searchPaths = this.scriptResolver.getSearchPath();
+ int index = 0;
+ while ( !flushCache && index < searchPaths.length ) {
+ if ( path.startsWith(searchPaths[index]) ) {
+ flushCache = true;
+ }
+ index++;
+ }
+ if ( flushCache ) {
+ this.cache.clear();
+ }
+ }
+ }
}
Modified:
sling/trunk/bundles/servlets/resolver/src/main/resources/OSGI-INF/metatype/metatype.properties
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/resolver/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=789698&r1=789697&r2=789698&view=diff
==============================================================================
---
sling/trunk/bundles/servlets/resolver/src/main/resources/OSGI-INF/metatype/metatype.properties
(original)
+++
sling/trunk/bundles/servlets/resolver/src/main/resources/OSGI-INF/metatype/metatype.properties
Tue Jun 30 12:53:14 2009
@@ -21,7 +21,7 @@
#
# This file contains localization strings for configuration labels and
# descriptions as used in the metatype.xml descriptor generated by the
-# the Sling SCR plugin
+# the Maven SCR plugin
servletresolver.name = Apache Sling Servlet/Script Resolver and Error Handler
servletresolver.description = The Sling Servlet and Script Resolver has \
@@ -43,4 +43,8 @@
servletresolver.scriptUser.description = This optional property can specify \
the repository user who is used to read the scripts. If none is specified \
the admin user is used by default.
+
+servletresolver.cacheSize.name = Cache Size
+servletresolver.cacheSize.description = This property configures the size of
the \
+ cache used for script resolution. A value lower than 5 disables the cache.
\ No newline at end of file