ACE-3077 - BM-0013: SOLR GC performance

- Reduce GC further
   - Non-blocking http params moved from remoteAPI to core
   - Code cleanup - tabs to spaces!

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@89214 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast 2014-10-27 13:37:07 +00:00
parent 9c13732661
commit 668c2f1f35

View File

@ -18,26 +18,10 @@
*/
package org.alfresco.util;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.alfresco.httpclient.HttpClientFactory;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.params.DefaultHttpParamsFactory;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.params.HttpParams;
import org.apache.commons.httpclient.util.DateUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.extensions.webscripts.connector.RemoteClient;
/**
@ -61,7 +45,7 @@ public class HttpClientHelper
protected HttpClient initialValue()
{
logger.debug("Creating HttpClient instance for thread: " + Thread.currentThread().getName());
return new HttpClient(new NonBlockingHttpParams());
return new HttpClient(new HttpClientFactory.NonBlockingHttpParams());
}
};
@ -73,244 +57,4 @@ public class HttpClientHelper
{
return httpClient.get();
}
/////////////////////////////////////////////////////////////////
// Helper classes
/**
* An extension of the DefaultHttpParamsFactory that uses a RRW lock pattern rather than
* full synchronization around the parameter CRUD - to avoid locking on many reads.
*
* @author Kevin Roast
*/
public static class NonBlockingHttpParamsFactory extends DefaultHttpParamsFactory
{
private volatile HttpParams httpParams;
/* (non-Javadoc)
* @see org.apache.commons.httpclient.params.DefaultHttpParamsFactory#getDefaultParams()
*/
@Override
public HttpParams getDefaultParams()
{
if (httpParams == null)
{
synchronized (this)
{
if (httpParams == null)
{
httpParams = createParams();
}
}
}
return httpParams;
}
/**
* NOTE: This is a copy of the code in {@link DefaultHttpParamsFactory}
* Unfortunately this is required because although the factory pattern allows the
* override of the default param creation, it does not allow the class of the actual
* HttpParam implementation to be changed.
*/
@Override
protected HttpParams createParams()
{
HttpClientParams params = new NonBlockingHttpParams(null);
params.setParameter(HttpMethodParams.USER_AGENT, "Spring Surf via Apache HttpClient/3.1");
params.setVersion(HttpVersion.HTTP_1_1);
params.setConnectionManagerClass(SimpleHttpConnectionManager.class);
params.setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
params.setHttpElementCharset("US-ASCII");
params.setContentCharset("ISO-8859-1");
params.setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
List<String> datePatterns = Arrays.asList(
new String[] {
DateUtil.PATTERN_RFC1123,
DateUtil.PATTERN_RFC1036,
DateUtil.PATTERN_ASCTIME,
"EEE, dd-MMM-yyyy HH:mm:ss z",
"EEE, dd-MMM-yyyy HH-mm-ss z",
"EEE, dd MMM yy HH:mm:ss z",
"EEE dd-MMM-yyyy HH:mm:ss z",
"EEE dd MMM yyyy HH:mm:ss z",
"EEE dd-MMM-yyyy HH-mm-ss z",
"EEE dd-MMM-yy HH:mm:ss z",
"EEE dd MMM yy HH:mm:ss z",
"EEE,dd-MMM-yy HH:mm:ss z",
"EEE,dd-MMM-yyyy HH:mm:ss z",
"EEE, dd-MM-yyyy HH:mm:ss z",
}
);
params.setParameter(HttpMethodParams.DATE_PATTERNS, datePatterns);
String agent = null;
try
{
agent = System.getProperty("httpclient.useragent");
}
catch (SecurityException ignore)
{
}
if (agent != null)
{
params.setParameter(HttpMethodParams.USER_AGENT, agent);
}
String preemptiveDefault = null;
try
{
preemptiveDefault = System.getProperty("httpclient.authentication.preemptive");
}
catch (SecurityException ignore)
{
}
if (preemptiveDefault != null)
{
preemptiveDefault = preemptiveDefault.trim().toLowerCase();
if (preemptiveDefault.equals("true"))
{
params.setParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, Boolean.TRUE);
}
else if (preemptiveDefault.equals("false"))
{
params.setParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, Boolean.FALSE);
}
}
String defaultCookiePolicy = null;
try
{
defaultCookiePolicy = System.getProperty("apache.commons.httpclient.cookiespec");
}
catch (SecurityException ignore)
{
}
if (defaultCookiePolicy != null)
{
if ("COMPATIBILITY".equalsIgnoreCase(defaultCookiePolicy))
{
params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
}
else if ("NETSCAPE_DRAFT".equalsIgnoreCase(defaultCookiePolicy))
{
params.setCookiePolicy(CookiePolicy.NETSCAPE);
}
else if ("RFC2109".equalsIgnoreCase(defaultCookiePolicy))
{
params.setCookiePolicy(CookiePolicy.RFC_2109);
}
}
return params;
}
}
/**
* @author Kevin Roast
*/
public static class NonBlockingHttpParams extends HttpClientParams
{
private HashMap<String, Object> parameters = new HashMap<String, Object>(8);
private ReadWriteLock paramLock = new ReentrantReadWriteLock();
public NonBlockingHttpParams()
{
super();
}
public NonBlockingHttpParams(HttpParams defaults)
{
super(defaults);
}
@Override
public Object getParameter(final String name)
{
// See if the parameter has been explicitly defined
Object param = null;
paramLock.readLock().lock();
try
{
param = this.parameters.get(name);
}
finally
{
paramLock.readLock().unlock();
}
if (param == null)
{
// If not, see if defaults are available
HttpParams defaults = getDefaults();
if (defaults != null)
{
// Return default parameter value
param = defaults.getParameter(name);
}
}
return param;
}
@Override
public void setParameter(final String name, final Object value)
{
paramLock.writeLock().lock();
try
{
this.parameters.put(name, value);
}
finally
{
paramLock.writeLock().unlock();
}
}
@Override
public boolean isParameterSetLocally(final String name)
{
paramLock.readLock().lock();
try
{
return (this.parameters.get(name) != null);
}
finally
{
paramLock.readLock().unlock();
}
}
@Override
public void clear()
{
paramLock.writeLock().lock();
try
{
this.parameters.clear();
}
finally
{
paramLock.writeLock().unlock();
}
}
@Override
public Object clone() throws CloneNotSupportedException
{
NonBlockingHttpParams clone = (NonBlockingHttpParams)super.clone();
paramLock.readLock().lock();
try
{
clone.parameters = (HashMap) this.parameters.clone();
}
finally
{
paramLock.readLock().unlock();
}
clone.setDefaults(getDefaults());
return clone;
}
}
}