Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What's the best practice when using pool in a package? #196

Open
niheaven opened this issue Dec 14, 2024 · 3 comments
Open

What's the best practice when using pool in a package? #196

niheaven opened this issue Dec 14, 2024 · 3 comments

Comments

@niheaven
Copy link

For instance, if I need to implement a connection pool within a package, how should I proceed?

Previously, I created pool::dbPool() in the .onLoad() function and closed it with reg.finalizer(), which worked well. However, adding more data sources would clutter the .onLoad() function. Also, how can I establish a connection to the database only when it's needed for the first time?

Furthermore, if I invoke the following function multiple times, will it create multiple connections in a single pool, or will it create multiple pools?

con <- function() {
  pool::dbPool(odbc::odbc(), driver = "Oracle Instant Client", dbq = "xxx", uid = "xxx", pwd = "xxx")
}

What would be the best approach in this scenario, or is there an example package that addresses this?

@hadley
Copy link
Member

hadley commented Jan 14, 2025

I think your initial idea makes the most sense to me (although I'd use .onUnload rather than reg.finalizer()). And I think if you set minSize = 0 then the pool will only create connections as you need them — the function you suggested will create multiple pools, which I doubt is what you want.

I'm not sure what your concern with creating multiple pools in .onLoad() is: you're going to have to put that code somewhere. If you're concerned with creating a bunch of pool objects, you might want to put them in a list.

@niheaven
Copy link
Author

Thank you! Here is my scenario: I have multiple data sources required by various packages, and I want to centralize the connection methods in a single auxiliary package. This would allow me to connect to any of the data sources by executing functions such as dbcons::db_a() or dbcons::db_b(). This led to my initial question.

Alternatively, if I could utilize pool within an environment in the auxiliary package, is this a better option?

@hadley
Copy link
Member

hadley commented Jan 21, 2025

Hmmmm, in that case I'd be tempted to do something like this:

the <- new.env()

con <- function() {
  if (is.null(the$con)) {
    the$con <- pool::dbPool(odbc::odbc(), driver = "Oracle Instant Client", dbq = "xxx", uid = "xxx", pwd = "xxx")
    reg.finalizer(the, function(env) pool::poolClose(env$con))
  }
  the$my_con
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants