-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

hi Matthijs + all,

just to let you know that setting the read timeout on the connection
solved the issue!  i'm attaching the patch i applied to the gt-main
module for the 2.7.3 release in case it's useful for somebody else.


On Thu, 20 Sep 2012 08:00:01 +1000
"Raif S. Naffah" <[email protected]> wrote:

> hi Matthijs,
> 
> thanks for the pointer!
> 
> looking through the commit i see where the same 'timeout' value is now
> being used to set the connection's connect as well as read timeouts.
> 
> it's unclear to me though how explicitly setting this property will
> work when setting the default socket read timeout is not --the
> - -Dsun.net.client.defaultReadTimeout-- but i'm willing to give
> this a try at this stage.
> 
> however switching to 2.7.4 may not be as simple as it sounds.
> patching the 2.7.3 version is much simpler.  i'll amend the
> AbstractOpenWebService code to set the connection's read timeout based
> on the value of a system environment named ows.client.readTimeout
> if/when set.
> 
> i'll follow up w/ the result after testing incl. the patch if it
> works.
> 
> 
> On Wed, 19 Sep 2012 09:52:32 +0200
> Matthijs Laan <[email protected]> wrote:
> 
> > Hi Raif,
> > 
> > I think the read timeout is set with the WebMapServer(URL, int) 
> > constructor in version 2.7.4 in which includes the patch for
> > GEOT-3860:
> > 
> > https://jira.codehaus.org/browse/GEOT-3860
> > https://github.com/geotools/geotools/commit/c70bc6ac2dcbd42401333e781fff882ed4db6625
> > 
> > Matthijs
> > 
> > On 2012-09-19 05:37, Raif S. Naffah wrote:
> > > hi there,
> > >
> > > this is not strictly a GeoTools library issue but i'm hoping some
> > > user / developer has seen this before and can shed some light and
> > > help me find a work-around.
> > >
> > > i'm using version 2.7.3 of the GeoTools WMS library:
> > > gt-wms-2.7.3.jar to build and submit a WMS GetMap request to a
> > > GeoServer (version 2.1.2), which btw. uses the same version of the
> > > GeoTools JARs.
> > >
> > > the problem i'm having is in one setup the GetMap request times
> > > out after 30 seconds.  here is the top of the stack trace:
> > >
> > > java.net.SocketTimeoutException: Read timed out
> > >   at java.net.SocketInputStream.socketRead0(Native Method)
> > >   at
> > > java.net.SocketInputStream.read(SocketInputStream.java:129) at
> > > java.io.BufferedInputStream.fill(BufferedInputStream.java:218) at
> > > java.io.BufferedInputStream.read1(BufferedInputStream.java:258) at
> > > java.io.BufferedInputStream.read(BufferedInputStream.java:317) at
> > > sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)
> > > at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632) at
> > > sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1049)
> > > at
> > > org.geotools.data.ows.AbstractOpenWebService.internalIssueRequest(AbstractOpenWebService.java:432)
> > > at
> > > org.geotools.data.wms.WebMapServer.issueRequest(WebMapServer.java:409)
> > >
> > > this 30-second 'barrier' happens even after forcing the JVM
> > > (Oracle java version "1.6.0_20") that contains the code causing
> > > the above is started w/ a
> > >
> > >    -Dsun.net.client.defaultReadTimeout=600000
> > >
> > > system property.
> > >
> > > i checked the source and there are 2 constructors for the
> > > WebMapServer type: one w/ the URL of the OGC server and the other
> > > w/ an additional 'timeout'.  i'm using the first one w/ the URL to
> > > the GeoServer only. the second constructor channels the 'timeout'
> > > value to the AbstractOpenWebService superclass and ultimately uses
> > > this value for 'connect' (not read) timeout --line #390:
> > >
> > >      connection.setConnectTimeout(this.requestTimeout);
> > >
> > > so from the look of it even if i use the 2nd constructor it does
> > > not look like it will be fixing my issue: read (not connect)
> > > timeout.  i should also mention that the request makes to the
> > > GeoServer end-point but the result does not make it back.
> > >
> > >
> > > the only 30-second limit i could find in the setup where the
> > > problem occurs is the 'maxIdleTime' property in the GeoServer's
> > > jetty.xml for the 'SelectChannelConnector' being used.
> > >
> > > anybody seen this or similar issue before?  ideas on solving or
> > > working around this is much appreciated.

- -- 
cheers;
rsn
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.18 (GNU/Linux)
Comment: Que du magnifique

iEYEAREDAAYFAlBb094ACgkQ+e1AKnsTRiE92wCfYyxjh2KjO8ncxTmlufZHODYO
JwMAoKPxObD/EMrUJQDMMAYhB9OlxGd/
=K2Bm
-----END PGP SIGNATURE-----
--- /shared/installs/G/GeoTools/geotools-2.7.3/modules/library/main/src/main/java/org/geotools/data/ows/AbstractOpenWebService.java
+++ /opt/workspace-2.7.3/geotools-2.7.3/modules/library/main/src/main/java/org/geotools/data/ows/AbstractOpenWebService.java
@@ -55,8 +55,11 @@
  * @source $URL$
  */
 public abstract class AbstractOpenWebService<C extends Capabilities, R extends Object> {
+    /** HTTP URL Connection read timeout in seconds. */
+    public static final String ENV_CLIENT_READ_TIMEOUT = "ows.client.readTimeout";
     /** Define a interval to wait a server response  */
     protected int requestTimeout = 30000; // 30 seconds
+    protected final int connectionReadTimeout;
     protected final URL serverURL;
     protected C capabilities;
     protected ServiceInfo info;
@@ -87,6 +90,28 @@
             throw new NullPointerException("ServerURL cannot be null");
         }
 
+        String envClientReadTimeout = System.getProperty(ENV_CLIENT_READ_TIMEOUT);
+        if (envClientReadTimeout != null && !envClientReadTimeout.trim().isEmpty()) {
+            envClientReadTimeout = envClientReadTimeout.trim();
+            LOGGER.info("ctor(URL,int): envClientReadTimeout = ["
+                    + envClientReadTimeout + "]");
+            int timeout;
+            try {
+                timeout = Integer.parseInt(envClientReadTimeout);
+                timeout *= 1000; // convert to millis.
+            } catch (NumberFormatException x) {
+                LOGGER.warning("ctor(URL,int): Failed parsing '"
+                        + envClientReadTimeout + "' to an integer. "
+                        + "Will use DEFAULT_TIMEOUT instead");
+                timeout = DEFAULT_TIMEOUT; // in millis.
+            }
+            connectionReadTimeout = timeout; // in millis.
+        } else {
+            connectionReadTimeout = DEFAULT_TIMEOUT; // in millis.
+        }
+        LOGGER.info("ctor(URL,int): connectionReadTimeout = "
+                + connectionReadTimeout + "ms.");
+
         this.serverURL = serverURL;
         this.requestTimeout = requestTimeout;
 
@@ -99,32 +124,54 @@
     }
     
     public AbstractOpenWebService(C capabilties, URL serverURL) {
-                if (capabilties == null) {
-                        throw new NullPointerException("Capabilities cannot be null.");
-                }
-                
-                if (serverURL == null) {
-                        throw new NullPointerException("ServerURL cannot be null");
-                }
-                
-                setupSpecifications();
-                
-                for (int i = 0; i < specs.length; i++) {
-                        if (specs[i].getVersion().equals(capabilties.getVersion())) {
-                                specification = specs[i];
-                                break;
-                        }
-                }
-                
-                if (specification == null) {
-                        specification = specs[specs.length-1];
-                        LOGGER.warning("Unable to choose a specification based on cached capabilities. "
-                                        +"Arbitrarily choosing spec '"+specification.getVersion()+"'.");
-                }
-                
-                this.serverURL = serverURL;
-                this.capabilities = capabilties;
-        }
+        if (capabilties == null) {
+            throw new NullPointerException("Capabilities cannot be null.");
+        }
+
+        if (serverURL == null) {
+            throw new NullPointerException("ServerURL cannot be null");
+        }
+
+        String envClientReadTimeout = System.getProperty(ENV_CLIENT_READ_TIMEOUT);
+        if (envClientReadTimeout != null && !envClientReadTimeout.trim().isEmpty()) {
+            envClientReadTimeout = envClientReadTimeout.trim();
+            LOGGER.info("ctor(C,URL): envClientReadTimeout = ["
+                    + envClientReadTimeout + "]");
+            int timeout;
+            try {
+                timeout = Integer.parseInt(envClientReadTimeout);
+                timeout *= 1000; // convert to millis.
+            } catch (NumberFormatException x) {
+                LOGGER.warning("ctor(C,URL): Failed parsing '"
+                        + envClientReadTimeout + "' to an integer. "
+                        + "Will use DEFAULT_TIMEOUT instead");
+                timeout = DEFAULT_TIMEOUT; // in millis.
+            }
+            connectionReadTimeout = timeout; // in millis.
+        } else {
+            connectionReadTimeout = DEFAULT_TIMEOUT; // in millis.
+        }
+        LOGGER.info("ctor(C,URL): connectionReadTimeout = "
+                + connectionReadTimeout + "ms.");
+
+        setupSpecifications();
+
+        for (int i = 0; i < specs.length; i++) {
+            if (specs[i].getVersion().equals(capabilties.getVersion())) {
+                specification = specs[i];
+                break;
+            }
+        }
+
+        if (specification == null) {
+            specification = specs[specs.length-1];
+            LOGGER.warning("Unable to choose a specification based on cached capabilities. "
+                    +"Arbitrarily choosing spec '"+specification.getVersion()+"'.");
+        }
+
+        this.serverURL = serverURL;
+        this.capabilities = capabilties;
+    }
 
     /**
      * Description of this service.
@@ -389,7 +436,16 @@
         
         connection.addRequestProperty("Accept-Encoding", "gzip");
         connection.setConnectTimeout(this.requestTimeout);
-        
+        if (connectionReadTimeout != DEFAULT_TIMEOUT) {
+            int oldValue = connection.getReadTimeout();
+            LOGGER.info("internalIssueRequest: About to change connection read "
+                    + "timeout from " + oldValue + " to " + connectionReadTimeout
+                    + "ms.");
+            connection.setReadTimeout(connectionReadTimeout);
+        }
+        LOGGER.info("internalIssueRequest: HTTP URL Connection will be using "
+                + connection.getReadTimeout() + "ms. as its read timeout");
+
         if (request.requiresPost()) {
                 connection.setRequestMethod("POST");
                 connection.setDoOutput(true);
------------------------------------------------------------------------------
Got visibility?
Most devs has no idea what their production app looks like.
Find out how fast your code is with AppDynamics Lite.
http://ad.doubleclick.net/clk;262219671;13503038;y?
http://info.appdynamics.com/FreeJavaPerformanceDownload.html
_______________________________________________
GeoTools-GT2-Users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users

Reply via email to