Attaching derby-6094-01-ac-enforceDriverManagerLoginTimeout.diff. This is the first rev of a patch to fix this issue. The new regression test is vacuous and needs to be beefed up with the actual test cases from the repro. I am attaching this patch because I would like to get advice and early feedback from the community.
At a high level, the patch does the following:
1) Enforces login timeouts on the embedded driver and data sources.
2) Makes client-side login timeouts conform to the JDBC 4.2 spec. That is, makes them raise SQLTimeoutException rather than the less refined SQLTransientException.
3) Adds a debug flag so that JUnit tests can be run with login timeouts set.
I would like the community's feedback on the following issues:
A) Login timeouts are NOT implemented for CDC/FP 1.1. This is because I used java.util.concurrent classes to implement login timeouts and those classes are not available on CDC/FP 1.1. I think that it should be possible to implement login timeouts using the Thread support in FP 1.1, but I think that the java.util.concurrent approach is going to be easier to understand and maintain and likely to be more robust. If someone cares about login timeouts on CDC/FP 1.1, please speak up. We can log another JIRA for adding that feature. Note that I'm not volunteering to do that work: it's not an important platform to me.
B) I am not sure what to do about Thread interrupts incurred during a timed login attempt. I would like advice from the experts on Derby interrupt handling. The attached patch simply wraps the interrupt exception in a SQLException. But maybe the right thing to do is to retry the login attempt until the timer expires. Or something else. I tripped across this problem while running InterruptResilienceTest with login timeouts. When I run that test like this...
java -Dderby.tests.login.timeout=10 junit.textui.TestRunner org.apache.derbyTesting.functionTests.tests.store.InterruptResilienceTest
...I get errors in testRAFReadWriteMultipleThreads. It looks to me like the following is happening: A WorkerThread catches an interrupted lock exception, which it expects will happen from time to time. The WorkerThread then goes on to create a new connection but gets another interrupt before the login timeout expires.
Touches the following files:
New SQLState for login timeouts. This is wrapped in a SQLTimeoutException on Java 6 and higher.
The guts of (1). This is where the java.util.concurrent classes are used to enforce login timeouts for the embedded driver.
The changes to the embedded driver resulted in an api change which percolated through the classes above.
This is the enforcement of (2), the raising of SQLTimeoutException on the client when the login timeout expires.
The changes for (3). Adds a new debug flag: derby.tests.login.timeout. You can set this to an integer, the length in seconds of the login timeout which you want to apply to all connection attempts. I have run the full JUnit suite with this flag set to 10. The tests run cleanly except for the following problems:
i) The errors in InterruptResilienceTest described above.
ii) I had to comment out NativeAuthenticationServiceTest. By itself, this test runs fine with derby.tests.login.timeout=10. However, when running the full JUnit suite with derby.tests.login.timeout=10, NativeAuthenticationServiceTest fails and its failure then chokes the rest of the suite. I need to investigate what's going on here.
This is the shell of a new test which will contain the cases from the repro.