Permalink
Browse files

propagating max connections when using DataSourceJdbcDataSource

  • Loading branch information...
renatocaval committed Nov 14, 2017
1 parent 19dc04a commit 1625f85753dccfe99e0d4dccdcfd69ccf13959c0
@@ -85,7 +85,7 @@ trait JdbcBackend extends RelationalBackend {
/** Create a Database based on a DataSource.
*
* @param ds The DataSource to use.
* @param maxConnection The maximum number of connections that the DataSource can provide. This is necessary to
* @param maxConnections The maximum number of connections that the DataSource can provide. This is necessary to
* prevent deadlocks when scheduling database actions. Use `None` if there is no hard limit.
* @param executor The AsyncExecutor for scheduling database actions.
* @param keepAliveConnection If this is set to true, one extra connection will be opened as soon as the database
@@ -97,18 +97,25 @@ trait JdbcBackend extends RelationalBackend {
/** Create a Database based on the JNDI name of a DataSource.
*
* @param ds The name of the DataSource to use.
* @param maxConnection The maximum number of connections that the DataSource can provide. This is necessary to
* @param name The name of the DataSource to use.
* @param maxConnections The maximum number of connections that the DataSource can provide. This is necessary to
* prevent deadlocks when scheduling database actions. Use `None` if there is no hard limit.
* @param executor The AsyncExecutor for scheduling database actions.
*/
def forName(name: String, maxConnections: Option[Int], executor: AsyncExecutor = null) = new InitialContext().lookup(name) match {
case ds: DataSource => forDataSource(ds, maxConnections, executor match {
case null => AsyncExecutor.default(name)
case e => e
})
case x => throw new SlickException("Expected a DataSource for JNDI name "+name+", but got "+x)
}
def forName(name: String, maxConnections: Option[Int], executor: AsyncExecutor = null) =
new InitialContext().lookup(name) match {
case ds: DataSource =>
val configuredExecutor =
(executor, maxConnections) match {
case (null, Some(maxConnec)) => AsyncExecutor.default(name, maxConnec)
case (null, None) => AsyncExecutor.default(name)
case (e, _) => e
}
forDataSource(ds, maxConnections, configuredExecutor)
case x => throw new SlickException("Expected a DataSource for JNDI name "+name+", but got "+x)
}
/** Create a Database that uses the DriverManager to open new connections. */
def forURL(url: String, user: String = null, password: String = null, prop: Properties = null, driver: String = null,
@@ -287,7 +294,7 @@ trait JdbcBackend extends RelationalBackend {
val source = JdbcDataSource.forConfig(usedConfig, driver, path, classLoader)
val poolName = usedConfig.getStringOr("poolName", path)
val numThreads = usedConfig.getIntOr("numThreads", 20)
val maxConnections = source.maxConnections.fold(numThreads)(identity)
val maxConnections = source.maxConnections.getOrElse(numThreads)
val registerMbeans = usedConfig.getBooleanOr("registerMbeans", false)
val executor = AsyncExecutor(poolName, numThreads, numThreads, usedConfig.getIntOr("queueSize", 1000),
maxConnections, registerMbeans = registerMbeans)
@@ -84,22 +84,26 @@ class DataSourceJdbcDataSource(val ds: DataSource, val keepAliveConnection: Bool
object DataSourceJdbcDataSource extends JdbcDataSourceFactory {
def forConfig(c: Config, driver: Driver, name: String, classLoader: ClassLoader): DataSourceJdbcDataSource = {
val ds = c.getStringOpt("dataSourceClass") match {
case Some(dsClass) =>
val propsO = c.getPropertiesOpt("properties")
try {
val ds = Class.forName(dsClass).newInstance.asInstanceOf[DataSource]
propsO.foreach(BeanConfigurator.configure(ds, _))
ds
} catch { case ex: Exception => throw new SlickException("Error configuring DataSource "+dsClass, ex) }
case None =>
val ds = new DriverDataSource
ds.classLoader = classLoader
ds.driverObject = driver
BeanConfigurator.configure(ds, c.toProperties, Set("url", "user", "password", "properties", "driver", "driverClassName"))
ds
}
new DataSourceJdbcDataSource(ds, c.getBooleanOr("keepAliveConnection"), None, new ConnectionPreparer(c))
val (ds, maxConnections) =
c.getStringOpt("dataSourceClass") match {
case Some(dsClass) =>
val propsO = c.getPropertiesOpt("properties")
try {
val ds = Class.forName(dsClass).newInstance.asInstanceOf[DataSource]
propsO.foreach(BeanConfigurator.configure(ds, _))
val maxConnections = c.getIntOpt("maxConnections")
(ds, maxConnections)
} catch { case ex: Exception => throw new SlickException("Error configuring DataSource " + dsClass, ex) }
case None =>
val ds = new DriverDataSource
ds.classLoader = classLoader
ds.driverObject = driver
BeanConfigurator.configure(ds, c.toProperties, Set("url", "user", "password", "properties", "driver", "driverClassName"))
(ds, None)
}
new DataSourceJdbcDataSource(ds, c.getBooleanOr("keepAliveConnection"), maxConnections, new ConnectionPreparer(c))
}
}
@@ -49,6 +49,7 @@ object AsyncExecutor extends Logging {
* queue and thread pool workload. */
def apply(name: String, minThreads: Int, maxThreads: Int, queueSize: Int, maxConnections: Int = Integer.MAX_VALUE, keepAliveTime: Duration = 1.minute,
registerMbeans: Boolean = false): AsyncExecutor = new AsyncExecutor {
@volatile private[this] lazy val mbeanName = new ObjectName(s"slick:type=AsyncExecutor,name=$name");
// Before init: 0, during init: 1, after init: 2, during/after shutdown: 3
@@ -184,6 +185,15 @@ object AsyncExecutor extends Logging {
}
}
def default(name: String, maxConnections: Int): AsyncExecutor =
apply(
name,
minThreads = 20,
maxThreads = 20,
queueSize = 1000,
maxConnections = maxConnections
)
def default(name: String = "AsyncExecutor.default"): AsyncExecutor =
apply(name, 20, 1000)

0 comments on commit 1625f85

Please sign in to comment.