None of the geocoder implementations seem to define timeout values. That's bad
in a production system. Here's an implementation that attempts to define as
many useful timeouts as possible:
/**
* @author Antti Koivisto
*/
public class TimeoutSafeGeoCoder extends Geocoder {
private static final int HTTP_CLIENT_CONNECTION_TIMEOUT = 5 * 1000; // 5 seconds
private static final int HTTP_CLIENT_METHOD_TIMEOUT = 5 * 1000; // 5 seconds
private static final int HTTP_CLIENT_MAX_CONNECTIONS = 200;
private static final int DEFAULT_URL_CONNECTION_TIMEOUT = 60 * 1000; // 60 seconds
private final HttpClient httpClient;
/**
* Use given connectionTimeout as HttpConnectionManagerParams.setConnectionTimeout();
* @param connectionTimeout
*/
public TimeoutSafeGeoCoder(int connectionTimeout) {
httpClient = setupHttpClient(connectionTimeout);
}
public TimeoutSafeGeoCoder() {
httpClient = setupHttpClient(DEFAULT_URL_CONNECTION_TIMEOUT);
}
public TimeoutSafeGeoCoder(final String clientId, final String clientKey) throws InvalidKeyException {
super(clientId, clientKey);
httpClient = setupHttpClient(DEFAULT_URL_CONNECTION_TIMEOUT);
}
private HttpClient setupHttpClient(int connectionTimeout) {
// As mapHandler may be used from several threads simultaneously, we must use HttpClient in
// thread-safe way (see http://hc.apache.org/httpclient-3.x/threading.html)
HttpConnectionManagerParams cmParams = new HttpConnectionManagerParams();
// maxConnectionsPerHost and maxTotalConnections must be set here, as the default values
// are not suitable for this use. As the FonectaMapHandler only connects to one host, we
// can use same number in both.
cmParams.setDefaultMaxConnectionsPerHost(HTTP_CLIENT_MAX_CONNECTIONS);
cmParams.setMaxTotalConnections(HTTP_CLIENT_MAX_CONNECTIONS);
cmParams.setConnectionTimeout(connectionTimeout);
MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
connectionManager.setParams(cmParams);
return new HttpClient(connectionManager);
}
protected GeocodeResponse request(Gson gson, String urlString) throws IOException {
final GetMethod getMethod = new GetMethod(urlString);
try {
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, new Integer(HTTP_CLIENT_METHOD_TIMEOUT));
httpClient.executeMethod(getMethod);
final Reader reader = new InputStreamReader(getMethod.getResponseBodyAsStream(), getMethod.getResponseCharSet());
return gson.fromJson(reader, GeocodeResponse.class);
} finally {
getMethod.releaseConnection();
}
}
}
Original issue reported on code.google.com by antti.p....@gmail.com on 29 Apr 2014 at 12:08
Original issue reported on code.google.com by
antti.p....@gmail.com
on 29 Apr 2014 at 12:08