Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Messenger] backport #54167: retry AMQPConnectionException on publish#1

Merged
modess merged 1 commit into
sweetspotio:amqps-supportfrom
gustaf-ag47:backport/amqp-connection-exception-retry
Apr 9, 2026
Merged

[Messenger] backport #54167: retry AMQPConnectionException on publish#1
modess merged 1 commit into
sweetspotio:amqps-supportfrom
gustaf-ag47:backport/amqp-connection-exception-retry

Conversation

@gustaf-ag47
Copy link
Copy Markdown

@gustaf-ag47 gustaf-ag47 commented Apr 9, 2026

Summary

Backports symfony/symfony#54167 into this 4.4 fork to fix intermittent AMQPS publish failures against AWS AmazonMQ.

Root cause

AWS NLB's 350s idle TCP timeout on TLS listeners silently kills AMQPS connections. ext-amqp's isConnected() does not detect the dead socket, so the next publish() hits OpenSSL on an RST'd socket and surfaces as Library error: a SSL error occurred / stream_socket_enable_crypto() warnings. This is exactly symfony/symfony#48241.

Fix

Wraps Connection::publish() in withConnectionExceptionRetry():

  • Catches only \AMQPConnectionException
  • Calls clear() to drop cached $amqpChannel / $amqpQueues / $amqpExchange / $amqpDelayExchange
  • Retries up to 3 times, no backoff (matches upstream)
  • Re-throws after exhausting retries

clearWhenDisconnected() refactored to delegate to the new clear() helper. Style matches the fork (direct = null assignment, not unset()).

Testing

  • php -l passes
  • Validated via a local vendor patch in the consuming app (sweetspotio/sweetspot-api-platform#4965), which has a unit test AmqpExtConnectionRetryTest covering retry-on-AMQPConnectionException, exhaustion after 3 retries, and clear() semantics (4/4 green)

Consumer

sweetspotio/sweetspot-api-platform#4965 will bump its composer pin to this fork HEAD once merged.

Upstream refs

Summary by CodeRabbit

  • Bug Fixes
    • Improved reliability of AMQP message publishing with automatic recovery when connection failures occur.

Ports the upstream Symfony 5.4/6.4 fix for symfony/symfony#48241 into
this 4.4 fork. Wraps Connection::publish() in withConnectionExceptionRetry()
which catches \AMQPConnectionException, drops cached channel/queues/exchanges
via clear(), and retries up to 3 times with no backoff.

Fixes intermittent AMQPS publish failures against AWS AmazonMQ caused by
AWS NLB's 350s idle TCP timeout silently killing connections — ext-amqp's
isConnected() doesn't detect the dead socket so the next publish surfaces
as "Library error: a SSL error occurred".

Upstream PR: symfony/symfony#54167
Upstream issue: symfony/symfony#48241
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

The publish() method in Connection.php now wraps its delay/publish/setup logic in a new withConnectionExceptionRetry() method that automatically retries operations up to 3 times when AMQP connection exceptions occur, clearing cached state between attempts.

Changes

Cohort / File(s) Summary
Retry Logic & Cache Management
Transport/AmqpExt/Connection.php
Added withConnectionExceptionRetry() wrapper method to publish() that retries on \AMQPConnectionException up to 3 times, clearing cached AMQP state (amqpChannel, amqpQueues, amqpExchange, amqpDelayExchange) before each retry. Refactored clearWhenDisconnected() to delegate cache resets to new clear() helper method.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A rabbit hops through AMQP's maze,
With retries bright and cache ablaze,
Three chances given to reconnect,
Clear and try—no need to fret!
Hop along, dear protocol friend! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically identifies the main change: backporting upstream PR #54167 to add retry logic for AMQP connection exceptions when publishing messages.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@gustaf-ag47
Copy link
Copy Markdown
Author

@CodeRabbit full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
Transport/AmqpExt/Connection.php (1)

464-472: Consider logging retry attempts for observability.

Silent retries can make debugging production issues harder. Adding a log entry when retries occur would help operators understand connection instability without examining metrics or traces.

Example (if a logger is available or can be injected):

// Inside the catch block, before clear():
// $this->logger?->warning('AMQP connection exception, retrying ({retries}/{maxRetries})', [...]);
$this->clear();

This is optional if the goal is strict parity with upstream.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Transport/AmqpExt/Connection.php` around lines 464 - 472, Add an
observability log inside the AMQPConnectionException catch in Connection.php so
retry attempts are recorded: inside the catch block that handles
\AMQPConnectionException for the $callable() invocation, emit a warning (using
$this->logger or an injected logger) that includes current $retries and
$maxRetries and the exception message/stack before calling $this->clear(), then
preserve the existing increment-and-goto retry behavior; reference the catch
around $callable(), the $retries/$maxRetries variables, and $this->clear() when
making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@Transport/AmqpExt/Connection.php`:
- Around line 464-472: Add an observability log inside the
AMQPConnectionException catch in Connection.php so retry attempts are recorded:
inside the catch block that handles \AMQPConnectionException for the $callable()
invocation, emit a warning (using $this->logger or an injected logger) that
includes current $retries and $maxRetries and the exception message/stack before
calling $this->clear(), then preserve the existing increment-and-goto retry
behavior; reference the catch around $callable(), the $retries/$maxRetries
variables, and $this->clear() when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: da2fac32-ab82-4570-ba90-a86f36a6eb3c

📥 Commits

Reviewing files that changed from the base of the PR and between f620068 and 18912b6.

📒 Files selected for processing (1)
  • Transport/AmqpExt/Connection.php

@modess modess merged commit fcd7a4a into sweetspotio:amqps-support Apr 9, 2026
1 check passed
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.

2 participants