From 0482db7a87e306b3d3d5e5a24ac72600fc85d86a Mon Sep 17 00:00:00 2001 From: hongwei Date: Thu, 21 Sep 2023 18:16:52 +0200 Subject: [PATCH] refactor/added the DatabaseConnectionPoolScheduler -WIP --- .../main/scala/bootstrap/liftweb/Boot.scala | 8 ++-- .../bootstrap/liftweb/CustomDBVendor.scala | 6 +-- .../DatabaseConnectionPoolScheduler.scala | 37 +++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 obp-api/src/main/scala/code/scheduler/DatabaseConnectionPoolScheduler.scala diff --git a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala index 87fed85dd..5f8bbd85a 100644 --- a/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala +++ b/obp-api/src/main/scala/bootstrap/liftweb/Boot.scala @@ -99,7 +99,7 @@ import code.metrics.{MappedConnectorMetric, MappedMetric, MetricArchive} import code.migration.MigrationScriptLog import code.model.dataAccess._ import code.model.dataAccess.internalMapping.AccountIdMapping -import code.model.{Consumer, _} +import code.model._ import code.obp.grpc.HelloWorldServer import code.productAttributeattribute.MappedProductAttribute import code.productcollection.MappedProductCollection @@ -108,7 +108,7 @@ import code.productfee.ProductFee import code.products.MappedProduct import code.ratelimiting.RateLimiting import code.remotedata.RemotedataActors -import code.scheduler.{DatabaseDriverScheduler, JobScheduler, MetricsArchiveScheduler} +import code.scheduler.{DatabaseDriverScheduler, JobScheduler, MetricsArchiveScheduler, DatabaseConnectionPoolScheduler} import code.scope.{MappedScope, MappedUserScope} import code.snippet.{OAuthAuthorisation, OAuthWorkedThanks} import code.socialmedia.MappedSocialMedia @@ -146,7 +146,7 @@ import net.liftweb.mapper._ import net.liftweb.sitemap.Loc._ import net.liftweb.sitemap._ import net.liftweb.util.Helpers._ -import net.liftweb.util.{DefaultConnectionIdentifier, Helpers, Props, Schedule, _} +import net.liftweb.util.{DefaultConnectionIdentifier, _} import org.apache.commons.io.FileUtils import scala.concurrent.{ExecutionContext, Future} @@ -263,6 +263,8 @@ class Boot extends MdcLoggable { LiftRules.unloadHooks.append(vendor.closeAllConnections_! _) DB.defineConnectionManager(net.liftweb.util.DefaultConnectionIdentifier, vendor) + DatabaseConnectionPoolScheduler.start(vendor, 10)// 10 seconds + logger.debug("ThreadPoolConnectionsScheduler.start(vendor, 10)") } if (APIUtil.getPropsAsBoolValue("logging.database.queries.enable", false)) { diff --git a/obp-api/src/main/scala/bootstrap/liftweb/CustomDBVendor.scala b/obp-api/src/main/scala/bootstrap/liftweb/CustomDBVendor.scala index db7890db4..03f3afb1c 100644 --- a/obp-api/src/main/scala/bootstrap/liftweb/CustomDBVendor.scala +++ b/obp-api/src/main/scala/bootstrap/liftweb/CustomDBVendor.scala @@ -22,7 +22,7 @@ class CustomDBVendor(driverName: String, private val logger = Logger(classOf[CustomDBVendor]) - protected def createOne: Box[Connection] = { + def createOne: Box[Connection] = { tryo{t:Throwable => logger.error("Cannot load database driver: %s".format(driverName), t)}{Class.forName(driverName);()} (dbUser, dbPassword) match { @@ -67,7 +67,7 @@ trait CustomProtoDBVendor extends ConnectionManager { /** * How is a connection created? */ - protected def createOne: Box[Connection] + def createOne: Box[Connection] /** * Test the connection. By default, setAutoCommit(false), @@ -138,7 +138,7 @@ trait CustomProtoDBVendor extends ConnectionManager { private def _closeAllConnections_!(cnt: Int): Unit = synchronized { - logger.info("Closing all connections") + logger.debug("Closing all connections") if (cnt > 10) ()//we only try this 10 times, else { freePool.foreach {c => tryo(c.close);} diff --git a/obp-api/src/main/scala/code/scheduler/DatabaseConnectionPoolScheduler.scala b/obp-api/src/main/scala/code/scheduler/DatabaseConnectionPoolScheduler.scala new file mode 100644 index 000000000..bcbd2015b --- /dev/null +++ b/obp-api/src/main/scala/code/scheduler/DatabaseConnectionPoolScheduler.scala @@ -0,0 +1,37 @@ +package code.scheduler + +import bootstrap.liftweb.CustomProtoDBVendor +import code.actorsystem.ObpLookupSystem +import code.util.Helper.MdcLoggable +import java.util.concurrent.TimeUnit +import scala.concurrent.duration._ + + +object DatabaseConnectionPoolScheduler extends MdcLoggable { + + private lazy val actorSystem = ObpLookupSystem.obpLookupSystem + implicit lazy val executor = actorSystem.dispatcher + private lazy val scheduler = actorSystem.scheduler + + def start(vendor: CustomProtoDBVendor, interval: Long): Unit = { + scheduler.schedule( + initialDelay = Duration(interval, TimeUnit.SECONDS), + interval = Duration(interval, TimeUnit.SECONDS), + runnable = new Runnable { + def run(): Unit = { + clearAllConnections(vendor) + } + } + ) + } + + def clearAllConnections(vendor: CustomProtoDBVendor) = { + //if the connection is Failure or empty, both is true + if (vendor.createOne.isEmpty) { + vendor.closeAllConnections_!() + logger.debug("ThreadPoolConnectionsScheduler.clearAllConnections") + } + } + + +}