Skip to content

[Messenger] Allow to close the transport connection #59862

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

Merged
merged 1 commit into from
Mar 5, 2025

Conversation

andrew-demb
Copy link
Contributor

@andrew-demb andrew-demb commented Feb 26, 2025

Q A
Branch? 7.3
Bug fix? no
New feature? yes
Deprecations? no
Issues Fix #53543
License MIT

1. Implemented the possibility to make messenger transports resettable
2. Implemented reset Redis connection for Redis messenger transport

This feature may lead to decreased performance for messenger consumers (because connection will be resetted between processing messages).

One way to resolve it that I found - add configuration for resettable transports - aka "reset connection on kernel reset: true/false". For consumers it can be configured via env var to be "false", but for web "true".


UPD 2025-02-27: According to the feedback, I changed the implementation to another one to help with our use case.

Implemented a way to close messenger transport from the application, to allow free resources for long-running processes (like a long-running webserver)

@andrew-demb
Copy link
Contributor Author

Error: src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php:59:13: UndefinedClass: Class, interface or enum named Relay\Relay does not exist (see https://psalm.dev/019)
Error: src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php:740:34: UndefinedClass: Class, interface or enum named Relay\Relay does not exist (see https://psalm.dev/019)

I don't know how to handle this error. I didn't add Relay in the PR - probably an issue introduced by the Psalm update or existed before.

@andrew-demb
Copy link
Contributor Author

.................................zend_mm_heap corrupted
Job exited with: 134
Error: KO src/Symfony/Component/Validator

This CI failure for PHP 8.5 seems unrelated to PR

@HypeMC
Copy link
Contributor

HypeMC commented Feb 26, 2025

At first glance, this looks like something that should be handled via a middleware, something like DoctrineCloseConnectionMiddleware.

@andrew-demb
Copy link
Contributor Author

@HypeMC my use-case - a long-running webserver. Some of the requests trigger symfony/messenger-related code.

If such a request is handled - Redis connection is not closed until the webserver worker will be restarted.

@stof
Copy link
Member

stof commented Feb 26, 2025

is it an issue that the Redis connection is not closed ? When using a long-running webserver instead of PHP-FPM, isn't one of the goals being able to keep such connections instead of reconnecting all the time ?

@andrew-demb
Copy link
Contributor Author

@stof As we're used (in our project) Redis for queues not so often, we're trying to avoid additional connections being opened to Redis with no reason (and other "cold" storages).

Just checked how Symfony behaves with Doctrine DBAL connections - they are not closed between requests either.

I'm OK with changing the PR implementation just to open the way to close connection (add method "close" to the Redis transport) - to allow close connection from the application code (using the event system).

What do you think about this? @stof @HypeMC

@ro0NL
Copy link
Contributor

ro0NL commented Feb 26, 2025

doctrine can be optionally closed at the middelware layer: https://github.com/symfony/symfony/blob/7.3/src/Symfony/Bridge/Doctrine/Messenger/DoctrineCloseConnectionMiddleware.php

im wondering if redis should follow a similar approach

@andrew-demb
Copy link
Contributor Author

I can introduce the interface "CloseableTransportInterface" that will allow closing used transport connections from the userland (in my case - from "kernel.terminate" event listener).

I can see, that this can be implemented by most transports (AMQP, Redis, Doctrine DBAL, etc)

@andrew-demb andrew-demb changed the title [Messenger] Reset Redis connection between requests [Messenger] Allow to close the messenger transport connection Feb 27, 2025
@andrew-demb andrew-demb force-pushed the 53543-redis-messenger-reset branch from 619bffb to edaf24a Compare February 27, 2025 17:57
@andrew-demb
Copy link
Contributor Author

According to the feedback, I changed the implementation to another one to help with our use case.

Implemented a way to close messenger transport from the application, to allow free resources for long-running processes (like a long-running webserver)

@@ -80,6 +80,12 @@ public function reset(): void
$this->doMysqlCleanup = false;
}

public function close(): void
{
$this->driverConnection->close();
Copy link
Member

Choose a reason for hiding this comment

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

this transport does not own the DBAL connection, so it should not close it either

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated. Other transports seem OK to me to be closeable (they remain their own connection or already have some "reset" methods).

Copy link
Contributor

@ro0NL ro0NL Feb 27, 2025

Choose a reason for hiding this comment

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

@stof from a messenger:consume POV i think doctrine transport is "closeable"

that's what DoctrineCloseConnectionMiddleware does no?

i tend to believe we should either solve it at the transport layer or the middleware layer in an agnostic matter IMHO

Copy link
Member

Choose a reason for hiding this comment

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

DoctrineCloseConnectionMiddleware is closing the connection if you enable that middleware.

the transport itself should not close the connection implicitly, because it is not owning the connection (the connection might be used for multiple purposes)

Copy link
Member

@fabpot fabpot left a comment

Choose a reason for hiding this comment

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

Can you add a note in the CHANGELOG file about the new interface?

@andrew-demb
Copy link
Contributor Author

status:needs review

@OskarStark OskarStark changed the title [Messenger] Allow to close the messenger transport connection [Messenger] Allow to close the transport connection Mar 4, 2025
@fabpot fabpot force-pushed the 53543-redis-messenger-reset branch from 28f85d4 to 9788aee Compare March 5, 2025 08:11
@fabpot
Copy link
Member

fabpot commented Mar 5, 2025

Thank you @andrew-demb.

@fabpot fabpot merged commit 89bae9c into symfony:7.3 Mar 5, 2025
8 checks passed
@fabpot fabpot mentioned this pull request May 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Disconnect Redis connection for symfony/redis-messenger on "kernel.reset"
6 participants