mattmar10
mattmar10

Reputation: 515

Session Configuration/Timeout with Slick 3

Is there a way to handle sessions explicitly in Slick 3? I currently have some code that looks like

def findUserByEmail(email: String): Option[User] = {

    val users = TableQuery[Users]
    val action = users.filter(_.email === email).result.headOption

    val result = db.run(action.transactionally)

    Await.result(result, Duration.Inf)
}

It works fine the first few times I run it, but then I start running into issues where it looks like connections/sessions are being left open (see below). This code is running inside aws lambda functions and I'm thinking I need to handle sessions more explicitly. How would I do this in Slick 3?

"errorMessage": "Timeout after 5000ms of waiting for a connection.",
    "errorType": "java.sql.SQLTimeoutException",
    "stackTrace": [
      "com.zaxxer.hikari.pool.BaseHikariPool.getConnection(BaseHikariPool.java:233)",
      "com.zaxxer.hikari.pool.BaseHikariPool.getConnection(BaseHikariPool.java:183)",
      "com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:93)",
      "slick.jdbc.hikaricp.HikariCPJdbcDataSource.createConnection(HikariCPJdbcDataSource.scala:18)",
      "slick.jdbc.JdbcBackend$BaseSession.<init>(JdbcBackend.scala:424)",
      "slick.jdbc.JdbcBackend$DatabaseDef.createSession(JdbcBackend.scala:47)",
      "slick.jdbc.JdbcBackend$DatabaseDef.createSession(JdbcBackend.scala:38)",
      "slick.basic.BasicBackend$DatabaseDef.acquireSession(BasicBackend.scala:218)",
      "slick.basic.BasicBackend$DatabaseDef.acquireSession$(BasicBackend.scala:217)",
      "slick.jdbc.JdbcBackend$DatabaseDef.acquireSession(JdbcBackend.scala:38)",
      "slick.basic.BasicBackend$DatabaseDef$$anon$2.run(BasicBackend.scala:239)",
      "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)",
      "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)",
      "java.lang.Thread.run(Thread.java:745)"
    ],
    "cause": {
      "errorMessage": "FATAL: remaining connection slots are reserved for non-replication superuser connections",
      "errorType": "org.postgresql.util.PSQLException",
      "stackTrace": [
        "org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2455)",
        "org.postgresql.core.v3.QueryExecutorImpl.readStartupMessages(QueryExecutorImpl.java:2586)",
        "org.postgresql.core.v3.QueryExecutorImpl.<init>(QueryExecutorImpl.java:113)",
        "org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:222)",
        "org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:52)",
        "org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:216)",
        "org.postgresql.Driver.makeConnection(Driver.java:404)",
        "org.postgresql.Driver.connect(Driver.java:272)",

Upvotes: 0

Views: 1406

Answers (1)

Anita Fronczak
Anita Fronczak

Reputation: 806

You could try to set query timeout. Like this:

db.run(action.transactionally.withStatementParameters(statementInit = st => st.setQueryTimeout(100)))

You can also set different properties on Hikari connection pool as below:

slick {
      // https://github.com/slick/slick/blob/master/slick-hikaricp/src/main/scala/slick/jdbc/hikaricp/HikariCPJdbcDataSource.scala
      dataSourceClass = "slick.jdbc.DriverDataSource"
      user = ${database.user}
      password = ${database.password}
      url = ${database.url}
      connectionPool = HikariCP
      maxConnections = 50
      numThreads = 10
      queueSize = 5000
      connectionInitSql = "SELECT 1;"
      connectionTestQuery = "SELECT 1;"
      registerMbeans = true

      properties = {
        driver = ${database.driver}
        url = ${database.url}
      }
 }

Upvotes: 1

Related Questions