The UnboundID LDAP SDK for Java version 0.9.10 has just been released. The release notes provide the complete set of changes, but this post will outline two of the most significant changes in this release.
Synchronous Mode
The LDAP SDK now includes an option to operate in synchronous mode. If an application using the LDAP SDK does not need to perform asynchronous operations, and if it does not attempt to process multiple operations on the same connection at the same time, then you can use the new synchronous mode to achieve a significant increase in throughput and reduction in response time. In my testing, I have generally seen a performance improvement of about 15-20% by enabling the option to use synchronous mode.
Prior to this release, the LDAP SDK only operated in an asynchronous manner, in which each connection had a dedicated reader thread that could be used to read responses from the server. Whenever a request was sent to the server, a blocking queue was used to provide communication between the reader thread and the thread that sent the request. After sending a request to the server, the thread that sent that request would block on this queue waiting for the response from the server to be provided by the reader thread. This design is necessary to be able to handle the possibility of asynchronous operations, in which multiple requests can be outstanding at the same time, but it does incur overhead as a result of thread synchronization and context switching. This asynchronous manner of communication is still the default, but if your application doesn’t need the ability to process multiple operations on the same connection at the same time, then you can choose to use the new synchronous mode for better performance.
To enable synchronous mode, all you need to do is to set the useSynchronousMode
connection option on the connection before it is established. For example:
LDAPConnectionOptions options = new LDAPConnectionOptions(); options.setUseSynchronousMode(true); LDAPConnection connection = new LDAPConnection(options, host, port, bindDN, password);
You shouldn’t need to make any other changes to your application, since everything else should be completely transparent. If you do attempt to invoke an asynchronous operation (or attempt to perform an abandon or invoke a cancel extended request, which rely on the ability to perform asynchronous operations), then the SDK will throw an LDAP exception with a “not supported” result.
The synchronous mode is completely compatible with the use of connection pools, and in fact if you are currently using connection pools in your application then it’s very likely that your application meets the requirements for using synchronous mode, since it’s not all that easy to invoke asynchronous operations using pooled connections or to use a pooled connection concurrently across multiple threads.
There has been some other restructuring in the LDAP SDK to provide for this capability, and those underlying changes may also provide some level of benefit even for applications using the default asynchronous mode.
Spurious “Server Down” Responses
A user reported periodically getting “server down” responses, especially when reading large result sets. In the UnboundID LDAP SDK for Java, the “server down” response indicates that a previously-established connection is no longer usable, and generally indicates one of two things:
- The connection between the client and the server has been lost unexpectedly, most likely because of a network problem or because the server closed the connection.
- The client encountered an unrecoverable error while decoding a response from the server that prevents it from being able to perform any more communication over that connection.
Upon closer investigation, I did find that there was a corner case in which the LDAP SDK could experience a problem if it was in the process of decoding a response from the server in which the entire LDAP message for the response was not sent all at once but instead came in multiple pieces and there was a delay of at least 50 milliseconds (which is the default socket timeout in asynchronous mode, needed to handle a corner case for StartTLS processing) when trying to read a subsequent piece of the response message. In this case, the LDAP SDK had a problem in which it would try to start reading a completely new response rather than finishing the old response, and it would encounter an unrecoverable decoding error when trying to read in the middle of the old message as if it were the beginning of a new one.
This problem has been corrected, and the LDAP SDK will now properly handle this condition and is more tolerant of delays encountered when reading a response in multiple segments.