Re: BasicDataSource restart()
Jerry, On 9/7/21 15:49, Jerry Malcolm wrote: On 9/7/2021 2:35 PM, Christopher Schultz wrote: Jerry, Rémy, On 9/3/21 07:15, Rémy Maucherat wrote: On Fri, Sep 3, 2021 at 2:46 AM Jerry Malcolm wrote: I have a requirement to start a new log database on the first of every month. I still need to have access to older monthly log databases. I do not want to create a bunch of hardcoded manually configured individual datasources, one for each month. I have a dynamic datasource solution that is completely implemented and working except for one little thing. I access the BasicDataSource implementation class for the datasource. I have an algorithm that substitutes _MM at the appropriate spot in the configured URL and then updates the url in the datasource. All of this works great. I can live with the fact that the datasource can only point to one database at a time. My concern is that once I transition to another database, there are existing connections in the pool that are already attached to the old database. I need to clear those out and start over. But I don't have the luxury of bouncing tomcat to clean it up. The apache commons BasicDataSource has a restart() method. But unfortunately that method is omitted from the Tomcat version. There is a close() method on the BasicDataSource. But I don't see anything that will re-open it after closing. I thought about changing maxActive to 0, and waiting for it to drain, then setting it back to the original value. None of these sound like an ideal solution. Without a restart() method, is there any other way to force all existing connections to close and start clean? The code is kept in sync with DBCP (with a bit of lag maybe), so these lifecycle methods were also added to Tomcat one year ago (9.0.38+ and 8.5.58+). We are using this at $work to bounce our database connection pools after TLS client certificate changes. This is the code we are using to reload the pool: try { Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup(getJNDIPath()); if(null == ds) throw new ServiceException("Cannot obtain DataSource"); if(isInstanceOf(ds, "org.apache.tomcat.dbcp.dbcp2.BasicDataSource") || isInstanceOf(ds, "org.apache.commons.dbcp2.BasicDataSource")) { return call(ds, "restart"); } } catch (Exception e) { org.apache.log4j.Logger.getLogger(this.getClass()).error("Failed to reload DataSource " + getJNDIPath()); } The call() method simply encapsulates all of the work to make a reflective method call to BasicDataSource.restart(). As Rémy points out, it requires a Tomcat version 9.0.38+ or 8.5.58+. Hope that helps, -chris Chris, I'll definitely try this. But I'm curious about the restart method. Is it some sort of a hidden method that's only available to reflection? Seems it would be a lot more straightforward to just make the restart method public like it is in the apache version of BasicDataSource. I'm not complaining. If this works, then fine. Just curious. It's not magic; that method is in there[1][2]. The only reason we call it reflectively is because we don't want to have compile-time dependencies on the Tomcat internal classes. -chris [1] https://commons.apache.org/proper/commons-dbcp/apidocs/org/apache/commons/dbcp2/BasicDataSource.html#restart-- [2] https://tomcat.apache.org/tomcat-8.5-doc/api/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.html#restart() - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: BasicDataSource restart()
On 9/7/2021 2:35 PM, Christopher Schultz wrote: Jerry, Rémy, On 9/3/21 07:15, Rémy Maucherat wrote: On Fri, Sep 3, 2021 at 2:46 AM Jerry Malcolm wrote: I have a requirement to start a new log database on the first of every month. I still need to have access to older monthly log databases. I do not want to create a bunch of hardcoded manually configured individual datasources, one for each month. I have a dynamic datasource solution that is completely implemented and working except for one little thing. I access the BasicDataSource implementation class for the datasource. I have an algorithm that substitutes _MM at the appropriate spot in the configured URL and then updates the url in the datasource. All of this works great. I can live with the fact that the datasource can only point to one database at a time. My concern is that once I transition to another database, there are existing connections in the pool that are already attached to the old database. I need to clear those out and start over. But I don't have the luxury of bouncing tomcat to clean it up. The apache commons BasicDataSource has a restart() method. But unfortunately that method is omitted from the Tomcat version. There is a close() method on the BasicDataSource. But I don't see anything that will re-open it after closing. I thought about changing maxActive to 0, and waiting for it to drain, then setting it back to the original value. None of these sound like an ideal solution. Without a restart() method, is there any other way to force all existing connections to close and start clean? The code is kept in sync with DBCP (with a bit of lag maybe), so these lifecycle methods were also added to Tomcat one year ago (9.0.38+ and 8.5.58+). We are using this at $work to bounce our database connection pools after TLS client certificate changes. This is the code we are using to reload the pool: try { Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup(getJNDIPath()); if(null == ds) throw new ServiceException("Cannot obtain DataSource"); if(isInstanceOf(ds, "org.apache.tomcat.dbcp.dbcp2.BasicDataSource") || isInstanceOf(ds, "org.apache.commons.dbcp2.BasicDataSource")) { return call(ds, "restart"); } } catch (Exception e) { org.apache.log4j.Logger.getLogger(this.getClass()).error("Failed to reload DataSource " + getJNDIPath()); } The call() method simply encapsulates all of the work to make a reflective method call to BasicDataSource.restart(). As Rémy points out, it requires a Tomcat version 9.0.38+ or 8.5.58+. Hope that helps, -chris Chris, I'll definitely try this. But I'm curious about the restart method. Is it some sort of a hidden method that's only available to reflection? Seems it would be a lot more straightforward to just make the restart method public like it is in the apache version of BasicDataSource. I'm not complaining. If this works, then fine. Just curious. Thx Jerry - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: BasicDataSource restart()
Jerry, Rémy, On 9/3/21 07:15, Rémy Maucherat wrote: On Fri, Sep 3, 2021 at 2:46 AM Jerry Malcolm wrote: I have a requirement to start a new log database on the first of every month. I still need to have access to older monthly log databases. I do not want to create a bunch of hardcoded manually configured individual datasources, one for each month. I have a dynamic datasource solution that is completely implemented and working except for one little thing. I access the BasicDataSource implementation class for the datasource. I have an algorithm that substitutes _MM at the appropriate spot in the configured URL and then updates the url in the datasource. All of this works great. I can live with the fact that the datasource can only point to one database at a time. My concern is that once I transition to another database, there are existing connections in the pool that are already attached to the old database. I need to clear those out and start over. But I don't have the luxury of bouncing tomcat to clean it up. The apache commons BasicDataSource has a restart() method. But unfortunately that method is omitted from the Tomcat version. There is a close() method on the BasicDataSource. But I don't see anything that will re-open it after closing. I thought about changing maxActive to 0, and waiting for it to drain, then setting it back to the original value. None of these sound like an ideal solution. Without a restart() method, is there any other way to force all existing connections to close and start clean? The code is kept in sync with DBCP (with a bit of lag maybe), so these lifecycle methods were also added to Tomcat one year ago (9.0.38+ and 8.5.58+). We are using this at $work to bounce our database connection pools after TLS client certificate changes. This is the code we are using to reload the pool: try { Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup(getJNDIPath()); if(null == ds) throw new ServiceException("Cannot obtain DataSource"); if(isInstanceOf(ds, "org.apache.tomcat.dbcp.dbcp2.BasicDataSource") || isInstanceOf(ds, "org.apache.commons.dbcp2.BasicDataSource")) { return call(ds, "restart"); } } catch (Exception e) { org.apache.log4j.Logger.getLogger(this.getClass()).error("Failed to reload DataSource " + getJNDIPath()); } The call() method simply encapsulates all of the work to make a reflective method call to BasicDataSource.restart(). As Rémy points out, it requires a Tomcat version 9.0.38+ or 8.5.58+. Hope that helps, -chris - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
RE: Calculate time to get a connection from JDBC Pool
Lasantha, > -Original Message- > From: Lasantha Samarakoon > Sent: Monday, September 06, 2021 10:22 PM > To: users@tomcat.apache.org > Subject: Calculate time to get a connection from JDBC Pool > > Hi all, > > I am working on Tomcat JDBC Pools and I have a requirement that needs to > calculate the total time it takes to get a connection from the JDBC pool. > This is to cover the entire connection borrowing process (includes connection > creation, setting up, validation, etc). The Tomcat version we are using is > 9.0.34. > > I tried playing around with the interceptors and also walked through the > respective implementation of Tomcat[1], but couldn't find any extensible > code segment to catch the before and after points of the get connection > flow. > > Appreciate your input on any possible solution for this. > > [1] > https://urldefense.com/v3/__https://github.com/apache/tomcat/tree/9.0.3 > 4/modules/jdbc-pool__;!!F9svGWnIaVPGSwU!6_tpBtEDTx2wg- > 2SBU2URViWoyhQPdrSNgVO7dErbhcA1-gh-KL_EtXutKh78PSXUt86mkU$ > > TIA, > Lasantha I don't have an example on hand, but it looks like there is an MBean with the property meanBorrowWaitTimeMillis. Enable JMX like this: https://tomcat.apache.org/tomcat-9.0-doc/jdbc-pool.html#JMX
Re: JNDIRealm does not retry on read timeouts or closed connections
Am 2021-09-06 um 11:21 schrieb Mark Thomas: On 06/09/2021 09:52, Osipov, Michael (LDA IT PLM) wrote: My question is: Mark, you have direct access to JBS, would you be willing to file this issue directly or do you want me to file through bugreport.java.com first and when it arrives in JBS you could drop a comment that this also affects Tomcat? Best if you create it and I comment. It is public: https://bugs.openjdk.java.net/projects/JDK/issues/JDK-8273402 and partially related https://bugs.openjdk.java.net/projects/JDK/issues/JDK-8273385 for error analysis purposes. Michael - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org