pingidentity / ldapsdk

UnboundID LDAP SDK for Java
Other
334 stars 81 forks source link

IdleTimeout parameter for pooled connections #161

Closed hmicc closed 6 months ago

hmicc commented 6 months ago

Hi, I didn't find an idle timeout parameter for pooled connections (like com.sun.jndi.ldap.connect.pool.timeout in JNDI), am I missing something or does it not exist?

We are interested in such a feature as we need to enforce that all clients close their connections cleanly before the server side idle timeout hits.

dirmgr commented 6 months ago

There isn't an idle timeout, but there is a maximum connection age, which will close and re-establish connections after they've been connected for a given amount of time. You can control that with the setMaxConnectionAgeMillis method.

If you really specifically need an idle timeout, you could write a custom LDAPConnectionPoolHealthCheck that overrides the ensureConnectionValidForContinuedUse method and checks the connection's getLastCommunicationTime value against the current time. If the difference is greater than the desired idle timeout period, then it could throw an exception, and the pool will discard it and create a new connection to take its place.

hmicc commented 6 months ago

Thanks Neil for the quick response and suggestions, much appreciated!

It would be nice if idle connections could be handled independently of connection age, so that active connections can remain open for a longer time. We could go with the custom check, but it's an overhead to implement this in hundreds of client applications and introduces more margin of error. And as it's a common property of other connection pool implementations, I think it would be useful to have it when moving to UnboundID SDK.

dirmgr commented 6 months ago

I've just committed a change that adds a new MaximumIdleDurationLDAPConnectionPoolHealthCheck class that can be configured in a connection pool as a health check to automatically have it close connections that have been idle for longer than a specified length of time. This should be included in the next release, which will likely be in a few months.

Note, however, that this might not be the best option in a lot of cases. If your connection pool is configured with a server set that includes multiple servers, then you probably should use the maximum connection age rather than an idle duration. In the event that one or more servers become unavailable, all of the connections that had previously been established to them will be migrated to other servers, and having a maximum connection age set will allow things to get back to a more balanced state in a relatively timely manner once things are back to a normal working state. Otherwise, once the pool establishes a connection to a given server, it will continue to use that connection and will assume it is just as good as any other connection in the pool until it detects that there might be an issue with it, so an imbalance created by a failure can last for a long time without a maximum connection age.

Also, if you have an environment in which connections will be considered invalid after remaining idle for a period of time, then you might want to consider an alternative health checking mechanism that actually involves communicating with the server (e.g., the GetEntryLDAPConnectionPoolHealthCheck). Not only will these kinds of health checks do a better job of actually ensuring that connections are usable and that the server is responsive and appears to be healthy, but the communication that they perform will prevent the connections from being considered idle.

hmicc commented 6 months ago

Amazing Neil, thanks a lot!

You are mentioning some valid points, we will probably use a combination of both parameters. On a side note, what do you think about a max-connection-age parameter for PingDirectory? We have some clients that don't/can't set a max-age (e.g. PingFederate, which is also the client that produces the most load), which leads to unbalanced load on our directory server backends.

dirmgr commented 6 months ago

The Ping Identity Directory Server does support both an idle time limit and an absolute maximum connection duration.

There are actually a few ways of configuring an idle time limit:

For an absolute maximum connection duration, regardless of how much or how recently the client has used that connection, you can use the maximum-connection-duration property in the client connection policy configuration.

hmicc commented 6 months ago

Thanks Neil for the amazing support. I didn't know about the maximum-connection-duration property for client connection policies, will try that out.