-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Add dynamic credentials support to Postgres #1941
Add dynamic credentials support to Postgres #1941
Conversation
I just closed #1349 as not-planned but it just occurred to me that if we pivot this to being callback that provides |
That seems like a good idea! I had a quick look at generalizing this approach in the way you described and the only thing that immediately jumps out as a potential blocker is: sqlx/sqlx-core/src/pool/mod.rs Lines 512 to 519 in 79ebd30
We would need to execute the callback in order to determine the kind, and if the callback returns a future this method would have to become |
Hmm, that is a problem, yeah. I would probably say that we shouldn't have the callback just return I'm conceiving of a new trait and impls for this: pub trait ConnectOptionsProvider<DB: Database>: Send + Sync + 'static {
type Error: Into<Box<dyn Error>>;
type Future: Future<Output = Result<DB::ConnectOptions, Self::Error>>;
fn any_kind(&self) -> AnyKind;
fn provide_connect_options(&self) -> Self::Future;
}
#[cfg(feature = "postgres")]
impl<F, Fut, E> ConnectOptionsProvider<Postgres> for F
where
F: Fn() -> Fut + Send + Sync + 'static,
E: Into<Box<dyn Error>>,
Fut: Future<Output = Result<PgConnectOptions, E>>
{
type Error = E;
type Future = Fut;
fn any_kind(&self) -> AnyKind { AnyKind::Postgres }
fn provide_connect_options(&self) -> Self::Future { (self)() }
}
// plus impls for other dbs We can't have a blanket impl of // Bikeshedding?
#[cfg(feature = "postgres")]
pub fn provide_pg_options_as_any<P: ConnectOptionsProvider<Postgres>>(provider: P) -> impl ConnectOptionsProvider<Any> {
struct PgWrapper<P>(P);
impl<P> ConnectOptionsProvider<Any> for PgWrapper<P>
where P: ConnectOptionsProvider<Postgres> {
type Error = P::Error;
type Future = futures_util::future::OkInto<P::Future, AnyConnectOptions>;
fn any_kind(&self) -> AnyKind { AnyKind::Postgres }
fn provide_connect_options(&self) -> Self::Future { self.0.provide_connect_options().ok_into() }
} And then |
@abonander I took that idea and ran with it. I think its definitely feasible and I was able to thread it through until I ran into one blocker which is the following: sqlx/sqlx-core/src/pool/mod.rs Line 493 in 58712ae
If the pool holds onto the What do you think? |
I think the easiest fix would just be to panic if an async |
Closing due to inactivity from the original author. @jamiebrynes7 I don't think I ever saw a PR from you, I'm still interested in your approach. |
Fixes #445.
We've been using this in development to refresh RDS tokens and it works pretty well. Some outstanding work is left to do error typing properly.