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

Preserve dynamic database connections on reconnect #53914

Merged
merged 5 commits into from
Dec 16, 2024

Conversation

nickakitch
Copy link
Contributor

This pull request is intended as a fix to Issue #53886 #53886

It introduces a way to automatically reconnect to dynamically built database connections.

Currently calling DB::build() with a configuration that is not registered in configuration files will create a new 'on demand' connection. However, should this connection fail, when Laravel attempts to reconnect it will fail with an InvalidArgumentException due to the connection configuration not existing.

With this PR, dynamically built connections are stored in a local registry within the DatabaseManager. When a reconnection is attempted, the framework can now correctly retrieve the configuration and re-establish the PDO connection without error.

Benefit to End Users:
Developers who dynamically create database connections at runtime will no longer need to manually register them in config() arrays or handle reconnections themselves. The framework now supports transparent reconnections out-of-the-box for these on-demand connections.

How It Makes Building Web Applications Easier:
Before this change, any "lost connection" scenario for dynamically built connections required workarounds, such as manually re-registering configurations or catching and recreating connections on each failure. Now, developers can rely on Laravel’s built-in reconnection logic, reducing boilerplate and complexity.

Code example:

Before: Dynamically built connections would fail on reconnection:

$connection = DB::build([
    'driver' => 'mysql',
    'database' => 'forge',
    'username' => 'root',
    'password' => 'secret',
]);

// If the connection is lost, calling $connection->reconnect() 
// will throw "Database connection [dynamic_something] not configured."

After: Dynamically built connections are registered and can reconnect seamlessly:

$connection = DB::build([
    'driver' => 'mysql',
    'database' => 'forge',
    'username' => 'root',
    'password' => 'secret',
]);

// If the connection is lost, calling reconnect() now works as expected:
$connection->reconnect(); // Automatically refreshes the PDO without errors.

The user experience is improved by removing a hidden pitfall in dynamic connection usage.

Nicholas Hunt added 3 commits December 16, 2024 22:12

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.

Verified

This commit was signed with the committer’s verified signature.
BobDotCom BobDotCom

Verified

This commit was signed with the committer’s verified signature.
BobDotCom BobDotCom
@taylorotwell
Copy link
Member

One concern I have is for long running processes like queue workers or Octane, we would now be building an infinitely growing array of connection configurations if a specific name is not passed to build.

Verified

This commit was signed with the committer’s verified signature.
BobDotCom BobDotCom

Verified

This commit was signed with the committer’s verified signature.
BobDotCom BobDotCom
@taylorotwell taylorotwell merged commit 28c0d24 into laravel:11.x Dec 16, 2024
38 checks passed
@taylorotwell
Copy link
Member

Tried to make name calculation a bit more deterministic.

@nickakitch
Copy link
Contributor Author

I like how you've done it, I was thinking of adding in a method to forgetConnection($name) or similar to manually offload the memory but I like your approach better

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.

None yet

2 participants