influxdb/sqlx-hotswap-pool
Jake Goulding e07bcd40c2 refactor: Remove unused dependencies
These were found by iterating over all of the dependencies of each
Cargo.toml, then grepping that crate for the dependency's name. If it
didn't show up, I attempted to remove it.

I left a few dependencies that this process flagged:

* generated_types
  - `pbjson`,`serde`. Apparently used by the generated code.

* grpc-router-test-gen
  - `prost`. Apparently used by the generated code.

* influxdb_iox
  - `heappy`. Doesn't appear used, but is behind enough feature
    flags that I don't care to reason about and it's already optional.
  - `tikv_jemalloc_sys`. Appears to be setting a feature flag of an
    indirect dependency.

* iox_gitops_adapter
  - `k8s_openapi`. Appears to be setting a feature flag of an indirect
    dependency.
2022-05-06 15:57:58 -04:00
..
src fix: Instead of using DATABASE_URL, use INFLUXDB_IOX_CATALOG_DSN and TEST_INFLUXDB_IOX_CATALOG_DSN 2022-03-07 11:02:58 -05:00
Cargo.toml refactor: Remove unused dependencies 2022-05-06 15:57:58 -04:00
README.md chore: port sqlx-hotswap-pool over from conductor (#3750) 2022-02-15 16:18:36 +00:00

README.md

sqlx-hotswap-pool

This crate implements a workaround for the lack of support for password rotation in the sqlx crate.

There is an upstream ticket for this Support rotating passwords #445. This crate offfers a more quick&dirty solution to the problem.

Problem

Some authentication methods for databases provide short lived passwords that must be regularly rotated.

Examples are: AWS IAM database authentication, HashiCorp Vault's dynamic role, ...

However, in sqlx once you create a pool you need to pass the connection string (which includes the credentials) and you can't change it afterwards. The pool will create one or more connections with those credentials.

Workaround

This crate implements a wrapper struct around a reference counted Pool smart pointer. This wrapper can then be updated using internal mutability (mutex protected) whenever the main binary detects a credentials refresh. Every subsequent use of the pool will use the new underlying pool.

This workaround has been designed to solve the problem of updating credentials, but it happens to work if you want to point your pool to an entirely different database as well.

If the credentials refresh happen before the existing credentials are invalidated, references to the previous pool can still be used for some time.

If the credentials refresh contextually invalidates the exsting credentials, the process will experience connection errors if they used the pool before it has been updated (and if they cloned the Arc before the update method has been called).

Already open connections will keep working in both cases.

Usage:

use sqlx_hotswap_pool::HotSwapPool;
use sqlx::{pool::PoolOptions, Pool, Postgres};
# async fn foo() {
let pool1: Pool<Postgres> = PoolOptions::new()
    .test_before_acquire(true)
    .connect("postgresql://user:pw1@localhost/db")
    .await
    .unwrap();

// create a HotSwapPool, a pool that wraps `pool1` and supports replacing it with another
let pool: HotSwapPool<Postgres> = HotSwapPool::new(pool1);

let pool2 = PoolOptions::new()
    .test_before_acquire(true)
    .connect("postgresql://user:pw2@localhost/db")
    .await
    .unwrap();
    
// replace the pool wrapped by the HotSwapPool with `pool2` instead of `pool1`
pool.replace(pool2);
# }