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

feat: Implement before_connect callback to modify connect options. #3057

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

fiadliel
Copy link

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.

@abonander
Copy link
Collaborator

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

@fiadliel fiadliel force-pushed the before_connect branch 2 times, most recently from d04530b to 94ccd05 Compare March 5, 2024 07:57
@fiadliel
Copy link
Author

fiadliel commented Mar 5, 2024

@abonander Rebased, thanks!

@abonander
Copy link
Collaborator

@fiadliel looks like the examples are failing to compile.

@fiadliel
Copy link
Author

fiadliel commented Mar 6, 2024

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).

sqlx-core/src/pool/inner.rs Outdated Show resolved Hide resolved
@tmh-mfr
Copy link

tmh-mfr commented Apr 23, 2024

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?

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
This changes the behavior slightly in a second way - an IO error
of type `ConnectionRefused` will cause a retry attempt.
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

Successfully merging this pull request may close these issues.

Support rotating passwords
3 participants