postgresql-jdbc.git / summary / log / commit / refs

commit    838d69acb8a549d4b857b4cf48e2e50d41a0d3a7
Author:   Kris Jurka <books@ejurka.com>
Date:     Tue Jun 02 00:22:58 2009 +0000

    Add a connection parameter for setting a socket read timeout.  This
    acts like a global query timeout that shuts down the connection if
    exceeded.  This can be used to detect dead network connections if you
    can reasonably estimate the upper bound of your queries.
    
    Art Gramlich


doc/pgjdbc.xml | 15 +++++++++++++- org/postgresql/Driver.java.in | 4 +++- org/postgresql/core/v2/ConnectionFactoryImpl.java | 15 +++++++++++++- org/postgresql/core/v3/ConnectionFactoryImpl.java | 13 +++++++++++- org/postgresql/ds/common/BaseDataSource.java | 24 ++++++++++++++++++++++- 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/doc/pgjdbc.xml b/doc/pgjdbc.xml index d66a5d8e..5a1b600c 100644 --- a/doc/pgjdbc.xml +++ b/doc/pgjdbc.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <!-- Copyright (c) 2004-2008, PostgreSQL Global Development Group - $PostgreSQL: pgjdbc/doc/pgjdbc.xml,v 1.36 2008/11/29 07:40:29 jurka Exp $ + $PostgreSQL: pgjdbc/doc/pgjdbc.xml,v 1.37 2009/02/03 04:37:45 jurka Exp $ --> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> @@ -591,6 +591,19 @@ Connection conn = DriverManager.getConnection(url); </listitem> </varlistentry> + <varlistentry> + <term><varname>socketTimeout</varname> = <type>int</type></term> + <listitem> + <para> + The timeout value used for socket read operations. If reading + from the server takes longer than this value, the connection is + closed. This can be used as both a brute force global query + timeout and a method of detecting network problems. The timeout + is specified in seconds and a value of zero means that it is disabled. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>tcpKeepAlive</varname> = <type>boolean</type></term> <listitem> diff --git a/org/postgresql/Driver.java.in b/org/postgresql/Driver.java.in index ed2f45b9..8e332a47 100644 --- a/org/postgresql/Driver.java.in +++ b/org/postgresql/Driver.java.in @@ -3,7 +3,7 @@ * Copyright (c) 2003-2008, PostgreSQL Global Development Group * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/Driver.java.in,v 1.76 2008/10/08 18:24:05 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/Driver.java.in,v 1.77 2008/11/29 07:40:30 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -449,6 +449,8 @@ public class Driver implements java.sql.Driver new String[] { "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2" } }, { "loginTimeout", Boolean.FALSE, "The login timeout, in seconds; 0 means no timeout beyond the normal TCP connection timout." }, + { "socketTimeout", Boolean.FALSE, + "The timeout value for socket read operations, in seconds; 0 means no timeout." }, { "tcpKeepAlive", Boolean.FALSE, "Enable or disable TCP keep-alive probe." }, { "stringtype", Boolean.FALSE, diff --git a/org/postgresql/core/v2/ConnectionFactoryImpl.java b/org/postgresql/core/v2/ConnectionFactoryImpl.java index db0f8a93..2ef00fe3 100644 --- a/org/postgresql/core/v2/ConnectionFactoryImpl.java +++ b/org/postgresql/core/v2/ConnectionFactoryImpl.java @@ -4,7 +4,7 @@ * Copyright (c) 2004, Open Cloud Limited. * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/core/v2/ConnectionFactoryImpl.java,v 1.16 2008/09/19 22:50:38 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/core/v2/ConnectionFactoryImpl.java,v 1.17 2008/09/30 03:42:48 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -64,6 +64,19 @@ public class ConnectionFactoryImpl extends ConnectionFactory { // Construct and send an ssl startup packet if requested. if (trySSL) newStream = enableSSL(newStream, requireSSL, info, logger); + + + // Set the socket timeout if the "socketTimeout" property has been set. + String socketTimeoutProperty = info.getProperty("socketTimeout", "0"); + try { + int socketTimeout = Integer.parseInt(socketTimeoutProperty); + if (socketTimeout > 0) { + newStream.getSocket().setSoTimeout(socketTimeout*1000); + } + } catch (NumberFormatException nfe) { + logger.info("Couldn't parse socketTimeout value:" + socketTimeoutProperty); + } + // Enable TCP keep-alive probe if required. newStream.getSocket().setKeepAlive(requireTCPKeepAlive); diff --git a/org/postgresql/core/v3/ConnectionFactoryImpl.java b/org/postgresql/core/v3/ConnectionFactoryImpl.java index b165ba7d..e1db7b7c 100644 --- a/org/postgresql/core/v3/ConnectionFactoryImpl.java +++ b/org/postgresql/core/v3/ConnectionFactoryImpl.java @@ -4,7 +4,7 @@ * Copyright (c) 2004, Open Cloud Limited. * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/core/v3/ConnectionFactoryImpl.java,v 1.18 2008/09/30 03:42:48 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/core/v3/ConnectionFactoryImpl.java,v 1.19 2008/11/29 07:40:30 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -78,6 +78,17 @@ public class ConnectionFactoryImpl extends ConnectionFactory { // Construct and send an ssl startup packet if requested. if (trySSL) newStream = enableSSL(newStream, requireSSL, info, logger); + + // Set the socket timeout if the "socketTimeout" property has been set. + String socketTimeoutProperty = info.getProperty("socketTimeout", "0"); + try { + int socketTimeout = Integer.parseInt(socketTimeoutProperty); + if (socketTimeout > 0) { + newStream.getSocket().setSoTimeout(socketTimeout*1000); + } + } catch (NumberFormatException nfe) { + logger.info("Couldn't parse socketTimeout value:" + socketTimeoutProperty); + } // Enable TCP keep-alive probe if required. newStream.getSocket().setKeepAlive(requireTCPKeepAlive); diff --git a/org/postgresql/ds/common/BaseDataSource.java b/org/postgresql/ds/common/BaseDataSource.java index c64f274e..7cd3790a 100644 --- a/org/postgresql/ds/common/BaseDataSource.java +++ b/org/postgresql/ds/common/BaseDataSource.java @@ -3,7 +3,7 @@ * Copyright (c) 2004-2008, PostgreSQL Global Development Group * * IDENTIFICATION -* $PostgreSQL: pgjdbc/org/postgresql/ds/common/BaseDataSource.java,v 1.13 2008/04/15 03:12:42 jurka Exp $ +* $PostgreSQL: pgjdbc/org/postgresql/ds/common/BaseDataSource.java,v 1.14 2008/05/21 19:54:21 jurka Exp $ * *------------------------------------------------------------------------- */ @@ -49,6 +49,7 @@ public abstract class BaseDataSource implements Referenceable private int portNumber; private int prepareThreshold; private int loginTimeout; // in seconds + private int socketTimeout; // in seconds private boolean ssl = false; private String sslfactory; private boolean tcpKeepAlive = false; @@ -274,6 +275,23 @@ public abstract class BaseDataSource implements Referenceable return prepareThreshold; } + /** + * Sets the socket timeout (SOTimeout), in seconds + */ + public void setSocketTimeout(int seconds) + { + this.socketTimeout = seconds; + } + + /** + * @return the socket timeout (SOTimeout), in seconds + */ + public int getSocketTimeout() + { + return this.socketTimeout; + } + + /** * Set whether the connection will be SSL encrypted or not. * @@ -338,6 +356,7 @@ public abstract class BaseDataSource implements Referenceable } sb.append("/").append(databaseName); sb.append("?loginTimeout=").append(loginTimeout); + sb.append("&socketTimeout=").append(socketTimeout); sb.append("&prepareThreshold=").append(prepareThreshold); if (ssl) { sb.append("&ssl=true"); @@ -383,6 +402,7 @@ public abstract class BaseDataSource implements Referenceable ref.add(new StringRefAddr("prepareThreshold", Integer.toString(prepareThreshold))); ref.add(new StringRefAddr("loginTimeout", Integer.toString(loginTimeout))); + ref.add(new StringRefAddr("socketTimeout", Integer.toString(socketTimeout))); ref.add(new StringRefAddr("ssl", Boolean.toString(ssl))); ref.add(new StringRefAddr("sslfactory", sslfactory)); @@ -405,6 +425,7 @@ public abstract class BaseDataSource implements Referenceable out.writeInt(portNumber); out.writeInt(prepareThreshold); out.writeInt(loginTimeout); + out.writeInt(socketTimeout); out.writeBoolean(ssl); out.writeObject(sslfactory); out.writeBoolean(tcpKeepAlive); @@ -420,6 +441,7 @@ public abstract class BaseDataSource implements Referenceable portNumber = in.readInt(); prepareThreshold = in.readInt(); loginTimeout = in.readInt(); + socketTimeout = in.readInt(); ssl = in.readBoolean(); sslfactory = (String)in.readObject(); tcpKeepAlive = in.readBoolean(); [parent: f020faf2d78e]