Skip to content

Improve db_pools init: do not crash if DB unavailable during startup (sqlx) #2932

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

Closed
wants to merge 2 commits into from

Conversation

cormacrelf
Copy link
Contributor

@cormacrelf cormacrelf commented Apr 14, 2025

Fixes #2931

Why?

When using Pool::connect[_with], sqlx attempts to connect to the given
database immediately, and the fairing will fail if there are any
problems in that attempt (beyond obvious configuration problems that are
found before hitting the network), e.g.:

  • the database is unavailable; or
  • the username/password is incorrect; or
  • the ssl configuration is invalid; or
  • any other connection issue.

There are a few pros and cons to this approach:

Pros:

  • In development, configuration errors are surfaced slightly faster

Cons:

  • Databases are expected to be unavailable sometimes. It does not
    normally crash a server if one becomes unavailable after startup,
    so why should it prevent a server from starting at all? See
    [deadpool's justification]{https://docs.rs/deadpool} for not crashing.
  • In production/testing, slower to debug configuration or networking
    errors as your edit-test loop now involves restarting an application
    rather than refreshing a page or trying a request again.
  • Causes database or configuration issues to appear as "failed
    deployments" in standard deployment scenarios.
  • Introduces hard ordering constraints on operator actions during
    database recovery, requiring reboots to follow a functioning database
    or applications not to be restarted at certain times

Effect of change

The sqlx backend now behaves like the deadpool backend: no connection
issues are surfaced during startup. You will not see them until you
attempt to get a connection from the pool. That means rocket will launch
and you can find problems like these in smoke tests.

## Why?

When using `Pool::connect[_with]`, sqlx attempts to connect to the given
database immediately, and the fairing will fail if there are any
problems in that attempt (beyond obvious configuration problems that are
found before hitting the network), e.g.:

- the database is unavailable; or
- the username/password is incorrect; or
- the ssl configuration is invalid; or
- any other connection issue.

There are a few pros and cons to this approach:

Pros:

- In development, configuration errors are surfaced slightly faster

Cons:

- Databases are expected to be unavailable sometimes. It does not
  normally crash a server if one becomes unavailable after startup,
  so why should it prevent a server from starting at all? See
  [deadpool's justification]{https://docs.rs/deadpool} for not crashing.
- In production/testing, slower to debug configuration or networking
  errors as your edit-test loop now involves restarting an application
  rather than refreshing a page or trying a request again.
- Causes database or configuration issues to appear as "failed
  deployments" in standard deployment scenarios.
- Introduces hard ordering constraints on operator actions during
  database recovery, requiring reboots to follow a functioning database
  or applications not to be restarted at certain times

## Effect of change

The sqlx backend now behaves like the deadpool backend: no connection
issues are surfaced during startup. You will not see them until you
attempt to get a connection from the pool. That means rocket will launch
and you can find problems like these in smoke tests.
@cormacrelf
Copy link
Contributor Author

Test failures are same as master

@cormacrelf cormacrelf changed the title Improve db_pools init: do not crash if DB unavailable during startup Improve db_pools init: do not crash if DB unavailable during startup (sqlx) Apr 14, 2025
Copy link
Collaborator

@the10thWiz the10thWiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good change. More generally, we should consider also attempting to detect database issues and report them, even if the server continues running.

This would likely take the form of spawning a task to pull a connection from the pool, and potentially run some kind of basic sql (e.g. select 1;). We could then provide an error log indicating that the db is currently inaccessible.

@the10thWiz
Copy link
Collaborator

Merged in 64ef4e9

@the10thWiz the10thWiz closed this May 4, 2025
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.

rocket_db_pools: Allow pool creation to succeed even if DB unavailable (sqlx, maybe others)
2 participants