Skip to content

Commit

Permalink
Reformat the postgres connection URL to work properly with unix socke…
Browse files Browse the repository at this point in the history
…t connections (Zondax#150)

I ran into a problem trying to connect `namadexer` to a postgres
database using a Unix domain socket rather than a network hostname. This
is necessary in order to run the `server` in environments like Google
Cloud Run, which exposes connections to Postgresql as a local domain
socket.

**The problem:**
* Google Cloud SQL creates a socket with a path like
`/cloudsql/namada:us-central1:namadexer-db-instance`
* Setting
`DATABASE_HOST=/cloudsql/namada:us-central1:namadexer-db-instance` would
produce a connection URL like the following:
    ```

postgres://postgres:wow@/cloudsql/namada:my-region:namadexer-db-instance:5432/blockchain
    ```
* This URL is not valid.

**The solution:**
* There is an alternate form for the postgres URL, like this:
    ```

postgres://postgres:wow@dummy-hostname:5432/blockchain?host=/cloudsql/namada:my-region:namadexer-db-instance
    ```
* In this case, the actual `host` can contain `/` and `:` characters
just fine.
* The `dummy-hostname` in the host part of the URL must be present for
the URL to be parsed properly, but is ignored.
  • Loading branch information
joel-u410 authored and tq-tuan15 committed Feb 23, 2024
1 parent a61f95a commit 6bb083f
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,25 @@ impl Database {
// sqlx expects config of the form:
// postgres://user:password@host:port/db_name
let config = format!(
"postgres://{}:{}@{}/{}",
db_config.user,
db_config.password,
db_config.host,
db_config.dbname
// In order to accommodate the use of a unix socket, we are actually supplying a dummy
// string "not-the-host" to the host portion of the URL, and putting the actual host in the
// query string. This is the only way to provide a "host" to sqlx that contains slashes.
// When "host=" is given as a query parameter, postgres ignores the host portion of the URL
// though it is still required to be present for the URL to parse correctly.
"postgres://{}:{}@not-the-host:{}/{}?host={}",
db_config.user, db_config.password, db_config.port, db_config.dbname, db_config.host
);

// If timeout setting is not present in the provided configuration,
// lets use our default timeout.
let timeout = db_config.connection_timeout.unwrap_or(DATABASE_TIMEOUT);

debug!(
"connecting to database at {} with timeout {}",
config.replace(&db_config.password, "*****"),
timeout
);

let pool = PgPoolOptions::new()
.max_connections(10)
.acquire_timeout(Duration::from_secs(timeout))
Expand Down

0 comments on commit 6bb083f

Please sign in to comment.