sqlx icon indicating copy to clipboard operation
sqlx copied to clipboard

feat: Implement before_connect callback to modify connect options.

Open fiadliel opened this issue 1 year ago • 5 comments

Allows the user to see and maybe modify the connect options before each attempt to connect to a database. May be used in a number of ways, e.g.:

  • adding jitter to connection lifetime
  • validating/setting a per-connection password
  • using a custom server discovery process

One approach to the issue in #3051 Also may help to fix #445

This is based on the signature suggestion from #3051. I'm not certain about the Error type used here; how should a user of the API represent an external error, sqlx::Error::Io?

Also, not sure how you would want this tested? The existing callback tests use a database connection which does not yet exist in this case.

fiadliel avatar Feb 13 '24 10:02 fiadliel

@fiadliel if you rebase it should fix the build failure.

abonander avatar Mar 05 '24 05:03 abonander

@abonander Rebased, thanks!

fiadliel avatar Mar 05 '24 07:03 fiadliel

@fiadliel looks like the examples are failing to compile.

abonander avatar Mar 06 '24 02:03 abonander

Fixed.

By the way, to show a concrete use case, I use this code to get a GCP access token (which has an expiry), this is then used as a password when connecting.

    PoolOptions::new()
        .before_connect(move |opts: &PgConnectOptions, _num_attempts| {
            let auth_manager = auth_manager.clone();
            Box::pin(async move {
                if let Ok(token) = auth_manager
                    .get_token(&["https://www.googleapis.com/auth/cloud-platform"])
                    .await
                {
                    Ok(Cow::Owned(opts.clone().password(token.as_str())))
                } else {
                    Err(sqlx::Error::Io(std::io::Error::other(
                        "failed to get token",
                    )))
                }
            })
        })

Updating the password in a background task is suboptimal, because (for various reasons) a background task is not guaranteed to run in time (e.g. there are systems that only run your code during an active request, and suspend them at other times).

fiadliel avatar Mar 06 '24 08:03 fiadliel

Hey there! We are using SeaORM in a new project and would would love to have this feature. Same usecase as @fiadliel mentioned, just on the AWS side. We get an access token via IAM which is only valid for 15 min.

Is there anyway I can help with getting this merged?

tmh-mfr avatar Apr 23 '24 09:04 tmh-mfr

Hi, I'm using this on Azure myself and would love to have this feature as well. One thing though: this will help with the creation of new connections but what happens to connections in the pool with the old password (token in my case)? Perhaps there could be a way to add some user defined meta data on acquire or connect or whatever where we could e.g. set the time of the token that was used for that connection and then on on_release we could destroy any connections which have the invalid token.

jason-johnson avatar Jul 01 '24 15:07 jason-johnson

Hi, I'm using this on Azure myself and would love to have this feature as well. One thing though: this will help with the creation of new connections but what happens to connections in the pool with the old password (token in my case)? Perhaps there could be a way to add some user defined meta data on acquire or connect or whatever where we could e.g. set the time of the token that was used for that connection and then on on_release we could destroy any connections which have the invalid token.

For AWS at least the old connections are fine - the token lasts for 15 minutes, but is only checked on connection. So once you're connected you can keep the connection open for hours. Are you sure Azure isn't the same?

ib353 avatar Jul 26 '24 13:07 ib353