how does Database.forDataSource work in slick? - scala

I am currently setting up a project that uses play slick with scala. From the docs I find that to get a session we should do
val db = Database.forDataSource(dataSource: javax.sql.DataSource)
So I followed the pattern and used this in every Repository layer.(A layer on top of model similar to a dao).
I have couple of repositories and I have duplicated this line .
My question is , does this connect to database every time of have a common pool and we get the connection from this pool ?

From slick documentation :
Using a DataSource
You can provide a DataSource object to forDataSource. If you got it from the connection pool of your application framework, this plugs the pool into Slick.
val db = Database.forDataSource(dataSource: javax.sql.DataSource)
When you later create a Session, a connection is acquired from the pool and when the Session is closed it is returned to the pool.

Related

How wildfly resets properties set on connection when returned to connection pool

I am doing jndi lookup for datasource configured in JBOSS
DataSource dataSource = (DataSource) new InitialContext().lookup(dataSourceStr);
return dataSource.getConnection();
Connection is closed by using try-with-resource.
Once I get connection object I'm setting isolation property on it, I need it for my functionality.
connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);//1
Once my operation is done I want to check what's isolation value present in connection for that I created connection object using similar mechanism given above and tested it's value which I found as TRANSACTION_READ_COMMITTED(2) which is default one and not which I had overriden. This is actually working as I wanted it to. I've not reset value to TRANSACTION_READ_COMMITTED(2) again once my operation is done but still it's getting reset to original TRANSACTION_READ_COMMITTED(2) when returned backed to pool. I m interested in knowing how this is happening/where can I look for more details.
I have kept only 1 connection in connection pool so I know when I accessed connection again I got the same connection object on which I had previously overriden value TRANSACTION_READ_UNCOMMITTED for isolation. I double checked it's by not closing connection thus it gave error when I tried to access it again.
My question is how connection value which was overriden is getting reset when it's getting back to pool?
could you please post the configuration of you DataSource?
This Behaviour is not specified by JBoss/WildFly it depends on the Implementation of DS you are using. So the behavior you are seeing can change between vendor specific implementations of DataSources.
For example if you are using postgres you could have a look on github.com/pgjdbc/pgjdbc/blob/… this is the listener which is fired when a pooled connection is closed.. but it seems postgres doesn't have such an "reset" behavior of it's pooled connections

Slick Database Instantiation And Connection Pool Logic

I am instantiating a slick database with code similar to
import slick.jdbc.JdbcBackend.Database
val db : Database = Database forConfig "configPath"
The query is constructed from a function that takes in a user id and returns a user name from the database table:
def queryName(userId : String) =
for {
row <- TableQuery[Tables.MyTable] if row.userid === userId
} yield row.username
And then running the query to produce distinct Publisher values:
val p1 : Publisher[String] = db stream (queryName("foo").result)
val p2 : Publisher[String] = db stream (queryName("bar").result)
Finally, my question is: Do multiple calls to db.stream utilize the same connection in the connection pool?
In other words, once I've instantiated the database is that the same as locking in on a single connection?
The implication would be that true utilization of all connections in the pool would require a function to create Database values before querying:
//Is this necessary?
val db = () => Database forConfig "configPath"
val p1 = db() stream (queryName("foo").result)
Thank you in advance for your consideration and response
According to Slick documentation about database thread pool:
When using Database.forConfig, the thread pool is configured directly in the external configuration file together with the connection parameters.
My hypothesis here is that you are using a connection pool (which is always recommended in production environments) and you have configured it properly in the external configuration file (the one referred by configPath).
You don't have to worry about database connections since your Database object (your db) is managing that for you.
Each call to db.stream() actually uses (and withdraw) a connection from the pool (eventually opening a new one according to the pool size and configuration) and releases it afterwards back into the pool.
For further details on how a connection pool works and how to configure (e.g. size) it in slick can be found at connection-pools.
An addictional note from adding-slick-to-your-project:
If you want to use Slick’s connection pool support, you need to add HikariCP as a dependency.

Server Swift with mongodb manager singleton

I am working on a project using Vapor and Mongodb.
Let's say that at a specific route
drop.get("user", String.self) { request, user in
// ... query Mongodb
}
I want to query the database and see if an input user already exists.
Is it wise to have a singleton MongoManager class that handles all the connection with the database?
drop.get("user", String.self) { request, user in
MongoManager.sharedInstance.findUser(user)
}
Do I create a bottleneck with this implementation?
No, you will not create a bottleneck unless you have a single-threaded mechanism that stands between your Vapor Handler and MongoDB.
MongoKitten (the underlying driver for Swift + MongoDB projects) manages the connection pool internally. You can blindly fire queries at MongoKitten and it'll figure out what connection to use or will create a new one if necessary.
Users of MongoKitten 3 will use a single connection per request. If multiple requests are being handled simultaneously, additional connections will be opened.
Users of MongoKitten 4 will use a single connection for 3 requests, this is configurable. The connection pool will expand by opening more connections if there are too many requests are being done.
Users of the upcoming Meow ORM (which works similar to what you're building) will use a single connection per thread. The connection pool will expand if all connections are reserved.

How to use Cashbah MongoDB connections?

Note: I realise there is a similar question on SO but it talks about an old version of Casbah, plus, the behaviour explained in the answer is not what I see!
I was under the impression that Casbah's MongoClient handled connection pooling. However, doing lsof on my process I see a big and growing number of mongodb connections, which makes me doubt this pooling actually exists.
Basically, this is what I'm doing:
class MongodbDataStore {
val mongoClient = MongoClient("host",27017)("database")
var getObject1(): Object1 = {
val collection = mongoClient("object1Collection")
...
}
var getObject2(): Object2 = {
val collection = mongoClient("object2Collection")
...
}
}
So, I never close MongoClient.
Should I be closing it after every query? Implement my own pooling? What then?
Thank you
Casbah is a wrapper around the MongoDB Java client, so the connection is actually managed by it.
According to the Java driver documentation (http://docs.mongodb.org/ecosystem/drivers/java-concurrency/) :
If you are using in a web serving environment, for example, you should
create a single MongoClient instance, and you can use it in every
request. The MongoClient object maintains an internal pool of
connections to the database (default maximum pool size of 100). For
every request to the DB (find, insert, etc) the Java thread will
obtain a connection from the pool, execute the operation, and release
the connection. This means the connection (socket) used may be
different each time.
By the way, that's what I've experienced in production. I did not see any problem with this.

Re-using sessions in ScalaQuery?

I need to do small (but frequent) operations on my database, from one of my api methods. When I try wrapping them into "withSession" each time, I get terrible performance.
db withSession {
SomeTable.insert(a,b)
}
Running the above example 100 times takes 22 seconds. Running them all in a single session is instantaneous.
Is there a way to re-use the session in subsequent function invocations?
Do you have some type of connection pooling (see JDBC Connection Pooling: Connection Reuse?)? If not you'll be using a new connection for every withSession(...) and that is a very slow approach. See http://groups.google.com/group/scalaquery/browse_thread/thread/9c32a2211aa8cea9 for a description of how to use C3PO with ScalaQuery.
If you use a managed resource from an application server you'll usually get this for "free", but in stand-alone servers (for example jetty) you'll have to configure this yourself.
I'm probably stating the way too obvious, but you could just put more calls inside the withSession block like:
db withSession {
SomeTable.insert(a,b)
SomeOtherTable.insert(a,b)
}
Alternately you can create an implicit session, do your business, then close it when you're done:
implicit val session = db.createSession
SomeTable.insert(a,b)
SomeOtherTable.insert(a,b)
session.close