Merge "Adding cache support to the jmx proxy" from Amnon
"Some of the nodetool commands calls multiple time to the same methods, specifically nodetool status and ring calls the endpoint snitch get rack and datacenter many times during the same command. It result in a long execution time. This series adds the ability to cache results when needed. Typically cached result will be for a few seconds, there is no need to a clean up mechanism as we don't expect there will be too much information in the cache. Currently the only cached results are for the endpoint snitch but it is easy to add more if we see that it is needed."
This commit is contained in:
commit
be8eea6bd4
@ -22,6 +22,7 @@ import javax.json.JsonReaderFactory;
|
||||
import javax.json.JsonString;
|
||||
import javax.management.openmbean.TabularData;
|
||||
import javax.management.openmbean.TabularDataSupport;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
@ -33,9 +34,29 @@ import com.sun.jersey.api.client.config.ClientConfig;
|
||||
import com.sun.jersey.api.client.config.DefaultClientConfig;
|
||||
import com.yammer.metrics.core.HistogramValues;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
public class APIClient {
|
||||
Map<String, CacheEntry> cache = new HashMap<String, CacheEntry>();
|
||||
String getCacheKey(String key, MultivaluedMap<String, String> param, long duration) {
|
||||
if (duration <= 0) {
|
||||
return null;
|
||||
}
|
||||
if (param != null) {
|
||||
StringBuilder sb = new StringBuilder(key);
|
||||
sb.append("?");
|
||||
for (String k : param.keySet()) {
|
||||
sb.append(k).append('=').append(param.get(k)).append('&');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return key;
|
||||
}
|
||||
String getFromCache(String key, long duration) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
CacheEntry value = cache.get(key);
|
||||
return (value!= null && value.valid(duration))? value.value : null;
|
||||
}
|
||||
JsonReaderFactory factory = Json.createReaderFactory(null);
|
||||
private static final java.util.logging.Logger logger = java.util.logging.Logger
|
||||
.getLogger(APIClient.class.getName());
|
||||
@ -105,15 +126,34 @@ public class APIClient {
|
||||
}
|
||||
|
||||
public String getRawValue(String string,
|
||||
MultivaluedMap<String, String> queryParams) {
|
||||
if (!string.equals("")) {
|
||||
return get(string, queryParams).get(String.class);
|
||||
MultivaluedMap<String, String> queryParams, long duration) {
|
||||
if (string.equals("")) {
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
String key = getCacheKey(string, queryParams, duration);
|
||||
String res = getFromCache(key, duration);
|
||||
if (res != null) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = get(string, queryParams).get(String.class);
|
||||
if (duration > 0) {
|
||||
cache.put(key, new CacheEntry(res));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public String getRawValue(String string,
|
||||
MultivaluedMap<String, String> queryParams) {
|
||||
return getRawValue(string, queryParams, 0);
|
||||
}
|
||||
|
||||
public String getRawValue(String string, long duration) {
|
||||
return getRawValue(string, null, duration);
|
||||
}
|
||||
|
||||
public String getRawValue(String string) {
|
||||
return getRawValue(string, null);
|
||||
return getRawValue(string, null, 0);
|
||||
}
|
||||
|
||||
public String getStringValue(String string, MultivaluedMap<String, String> queryParams) {
|
||||
@ -121,6 +161,11 @@ public class APIClient {
|
||||
queryParams).replaceAll("^\"|\"$", "");
|
||||
}
|
||||
|
||||
public String getStringValue(String string, MultivaluedMap<String, String> queryParams, long duration) {
|
||||
return getRawValue(string,
|
||||
queryParams, duration).replaceAll("^\"|\"$", "");
|
||||
}
|
||||
|
||||
public String getStringValue(String string) {
|
||||
return getStringValue(string, null);
|
||||
}
|
||||
|
20
src/main/java/com/cloudius/urchin/api/CacheEntry.java
Normal file
20
src/main/java/com/cloudius/urchin/api/CacheEntry.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2015 Cloudius Systems
|
||||
*/
|
||||
|
||||
package com.cloudius.urchin.api;
|
||||
|
||||
public class CacheEntry {
|
||||
long time;
|
||||
public String value;
|
||||
|
||||
CacheEntry(String value) {
|
||||
time = System.currentTimeMillis();
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean valid(long duration) {
|
||||
return (System.currentTimeMillis() - time) < duration;
|
||||
}
|
||||
|
||||
}
|
@ -57,10 +57,11 @@ public class EndpointSnitchInfo implements EndpointSnitchInfoMBean {
|
||||
/**
|
||||
* Provides the Rack name depending on the respective snitch used, given the
|
||||
* host name/ip
|
||||
*
|
||||
*
|
||||
* @param host
|
||||
* @throws UnknownHostException
|
||||
*/
|
||||
@Override
|
||||
public String getRack(String host) throws UnknownHostException {
|
||||
log("getRack(String host) throws UnknownHostException");
|
||||
MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
|
||||
@ -68,16 +69,17 @@ public class EndpointSnitchInfo implements EndpointSnitchInfoMBean {
|
||||
host = InetAddress.getLoopbackAddress().getHostAddress();
|
||||
}
|
||||
queryParams.add("host", host);
|
||||
return c.getStringValue("/snitch/rack", queryParams);
|
||||
return c.getStringValue("/snitch/rack", queryParams, 10000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the Datacenter name depending on the respective snitch used,
|
||||
* given the hostname/ip
|
||||
*
|
||||
*
|
||||
* @param host
|
||||
* @throws UnknownHostException
|
||||
*/
|
||||
@Override
|
||||
public String getDatacenter(String host) throws UnknownHostException {
|
||||
log(" getDatacenter(String host) throws UnknownHostException");
|
||||
MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
|
||||
@ -85,14 +87,15 @@ public class EndpointSnitchInfo implements EndpointSnitchInfoMBean {
|
||||
host = InetAddress.getLoopbackAddress().getHostAddress();
|
||||
}
|
||||
queryParams.add("host", host);
|
||||
return c.getStringValue("/snitch/datacenter", queryParams);
|
||||
return c.getStringValue("/snitch/datacenter", queryParams, 10000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the snitch name of the cluster
|
||||
*
|
||||
*
|
||||
* @return Snitch name
|
||||
*/
|
||||
@Override
|
||||
public String getSnitchName() {
|
||||
log(" getSnitchName()");
|
||||
return c.getStringValue("/snitch/name");
|
||||
|
Loading…
Reference in New Issue
Block a user