You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by "Mamta A. Satoor (JIRA)" <ji...@apache.org> on 2010/08/06 22:29:16 UTC

[jira] Issue Comment Edited: (DERBY-2026) Setting a login timeout in client driver can lead to query timeout

    [ https://issues.apache.org/jira/browse/DERBY-2026?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12894607#action_12894607 ] 

Mamta A. Satoor edited comment on DERBY-2026 at 8/6/10 4:27 PM:
----------------------------------------------------------------

The issue is setting a login timeout is also causing the queries to time out within that time. I did some debugging of the code and following is what I saw.

It appears that if the user has asked for login timeout, then during the connection setup time , we call setSoTimeout on the the socket which is used for communication. 

The api defination for setSoTimeout api on Socket says follows
public void setSoTimeout(int timeout) throws SocketException 
	Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a 
	non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this 
	amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the 
	Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. 
	The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout. 
Parameters:
timeout - the specified timeout, in milliseconds. 
Throws: 
SocketException - if there is an error in the underlying protocol, such as a TCP error.

So, it looks like that this setSoTimeout setting is applicable not just for the login time but also for every interaction after that 
which in our test case includes the query execution. 

The code path for setSoTimeout call on socket through our connection set up is as follows
Thread [main] (Suspended)	
	NetAgent.<init>(NetConnection, LogWriter, int, String, int, int) line: 142	
	NetConnection.newAgent_(LogWriter, int, String, int, int) line: 1016	
	NetConnection(Connection).<init>(LogWriter, int, String, int, String, Properties) line: 322	
	NetConnection.<init>(NetLogWriter, int, String, int, String, Properties) line: 208	
	ClientJDBCObjectFactoryImpl.newNetConnection(LogWriter, int, String, int, String, Properties) line: 270	
	ClientDriver.connect(String, Properties) line: 140	
	DriverManager.getConnection(String, Properties, ClassLoader) line: 572	
	DriverManager.getConnection(String) line: 218	
	Derby2026LoginTimeout.main(String[]) line: 52	
In the stack above, Derby2026LoginTimeout is the repro provided in the jira. I just changed the repro's name and the jdbc url inside the repro.

I am not sure at this point how(or if it can be done) but may be a fix would be to have the setSoTimeout be set only while the connection is being made. Once we have the connection, go back and rest the setSoTimeout to 0. I noticed following api in derby.client.net.NetAgent.java
    protected void setTimeout(int timeout) 
This api changes the timeout on socket to the passed value. I wonder if this api can be somehow used to change the timeout value to 0 after the connection has been established. As of right now, there is only one caller to NetAgent.setTimeout method and that call is from derby.client.Net.NetConnection40.isValid(int) method.

      was (Author: mamtas):
    The issue is setting a login timeout is also causing the queries to time out within that time. I did some debugging of the code and following is what I saw.

It appears that if the user has asked for login timeout, then during the connection setup time , we call setSoTimeout on the the socket which is used for communication. 

The JDBC defines setSoTimeout api on Socket as follows
public void setSoTimeout(int timeout) throws SocketException 
	Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a 
	non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this 
	amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the 
	Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. 
	The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout. 
Parameters:
timeout - the specified timeout, in milliseconds. 
Throws: 
SocketException - if there is an error in the underlying protocol, such as a TCP error.

So, it looks like that this setSoTimeout setting is applicable not just for the login time but also for every interaction after that 
which in our test case includes the query execution. 

The code path for setSoTimeout call on socket through our connection set up is as follows
Thread [main] (Suspended)	
	NetAgent.<init>(NetConnection, LogWriter, int, String, int, int) line: 142	
	NetConnection.newAgent_(LogWriter, int, String, int, int) line: 1016	
	NetConnection(Connection).<init>(LogWriter, int, String, int, String, Properties) line: 322	
	NetConnection.<init>(NetLogWriter, int, String, int, String, Properties) line: 208	
	ClientJDBCObjectFactoryImpl.newNetConnection(LogWriter, int, String, int, String, Properties) line: 270	
	ClientDriver.connect(String, Properties) line: 140	
	DriverManager.getConnection(String, Properties, ClassLoader) line: 572	
	DriverManager.getConnection(String) line: 218	
	Derby2026LoginTimeout.main(String[]) line: 52	
In the stack above, Derby2026LoginTimeout is the repro provided in the jira. I just changed the repro's name and the jdbc url inside the repro.

I am not sure at this point how(or if it can be done) but may be a fix would be to have the setSoTimeout be set only while the connection is being made. Once we have the connection, go back and rest the setSoTimeout to 0. I noticed following api in derby.client.net.NetAgent.java
    protected void setTimeout(int timeout) 
This api changes the timeout on socket to the passed value. I wonder if this api can be somehow used to change the timeout value to 0 after the connection has been established. As of right now, there is only one caller to NetAgent.setTimeout method and that call is from derby.client.Net.NetConnection40.isValid(int) method.
  
> Setting a login timeout in client driver can lead to query timeout
> ------------------------------------------------------------------
>
>                 Key: DERBY-2026
>                 URL: https://issues.apache.org/jira/browse/DERBY-2026
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC, Network Client
>    Affects Versions: 10.3.1.4
>         Environment: Client driver on most platforms
>            Reporter: Olav Sandstaa
>            Assignee: Mamta A. Satoor
>            Priority: Minor
>         Attachments: LoginTimeout.java
>
>
> Setting the login timeout by using DriverManager.setLoginTimeout(int
> seconds) also affects the amount of time the client driver is waiting
> for a query to finish. For instance, setting the login timeout to 10
> seconds will result in any queries taking more than 10 seconds to fail
> with the following exception:
> Exception thrown: java.sql.SQLException: A communications error has been detected: Read timed out.
> java.sql.SQLException: A communications error has been detected: Read timed out.
>         at org.apache.derby.client.am.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:46)
>         at org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:345)
>         at org.apache.derby.client.am.Statement.executeQuery(Statement.java:414)
>         at LoginTimeout.main(LoginTimeout.java:53)
> Caused by: org.apache.derby.client.am.DisconnectException: A communications error has been detected: Read timed out.
>         at org.apache.derby.client.net.NetAgent.throwCommunicationsFailure(NetAgent.java:408)
>         at org.apache.derby.client.net.Reply.fill(Reply.java:176)
>         at org.apache.derby.client.net.Reply.ensureALayerDataInBuffer(Reply.java:215)
>         at org.apache.derby.client.net.Reply.readDssHeader(Reply.java:317)
>         at org.apache.derby.client.net.Reply.startSameIdChainParse(Reply.java:1147)
>         at org.apache.derby.client.net.NetStatementReply.readPrepareDescribeOutput(NetStatementReply.java:51)
>         at org.apache.derby.client.net.StatementReply.readPrepareDescribeOutput(StatementReply.java:40)
>         at org.apache.derby.client.net.NetStatement.readPrepareDescribeOutput_(NetStatement.java:139)
>         at org.apache.derby.client.am.Statement.readPrepareDescribeOutput(Statement.java:1341)
>         at org.apache.derby.client.am.Statement.flowExecute(Statement.java:1977)
>         at org.apache.derby.client.am.Statement.executeQueryX(Statement.java:420)
>         at org.apache.derby.client.am.Statement.executeQuery(Statement.java:405)
>         ... 1 more
> Caused by: java.net.SocketTimeoutException: Read timed out
>         at java.net.SocketInputStream.socketRead0(Native Method)
>         at java.net.SocketInputStream.read(SocketInputStream.java:129)
>         at org.apache.derby.client.net.Reply.fill(Reply.java:174)
>         ... 11 more

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.