If you do this, HikariCP is init and shut down each time. Is there any way to avoid this and execute various queries?
// Resource yielding a transactor configured with a bounded connect EC and an unbounded
// transaction EC. Everything will be closed and shut down cleanly after use.
val transactor: Resource[IO, HikariTransactor[IO]] =
for {
ce <- ExecutionContexts.fixedThreadPool[IO](32) // our connect EC
be <- Blocker[IO] // our blocking EC
xa <- HikariTransactor.newHikariTransactor[IO](
"org.h2.Driver", // driver classname
"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", // connect URL
"sa", // username
"", // password
ce, // await connection here
be // execute JDBC operations here
)
} yield xa
run
transactor.use(sql"select 42".query[Int].unique.transact[IO]).unsafeRunSync()
This is not how you use Resource
s in application.
You do do .use
somewhere on main
level, and then let your whole code requiring Transactor
get that value passed, e.g:
val actorSystemResource: Resource[IO, ActorSystem]
val transactorResource: Resource[IO, Transactor[IO]]
// initialize controllers, services, etc and create routes for them
def routes(actorSystem: ActorSystem, transactor: Transactor[IO]): Route
val resources = for {
transactor <- transactorResource
actorSystem, <- actorSystemResource
route = routes(actorSystem, transactor)
} yield (transactor, actorSystem, route)
resources.use { case (_, actorSystem, route) =>
implicit system = actorSystem
IO.fromFuture {
Http().bindAndHandle(route, "localhost", 8080)
}
}
Alternatively, you can use resource.allocated
, but it almost certainly would be a bad idea, resulting in a code that never runs the release part of the Bracket
because it is easy to mess up and e.g. not calling it if some exception is thrown.