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.