Skip to content

feat(redis source): add reconnecting pubsub session for channel data_type#25892

Open
artusmode wants to merge 2 commits into
vectordotdev:masterfrom
artusmode:redis-channel-reconnect-finish
Open

feat(redis source): add reconnecting pubsub session for channel data_type#25892
artusmode wants to merge 2 commits into
vectordotdev:masterfrom
artusmode:redis-channel-reconnect-finish

Conversation

@artusmode

Copy link
Copy Markdown

Supersedes #24100 (rebased onto master; original work by @gibranbadrul, preserved as the first commit). Closes #22615.

The redis source with data_type = "channel" currently stops receiving after any Redis connection drop and only recovers on a Vector restart. This adds a reconnect loop that re-connects and re-subscribes automatically, with exponential backoff.

Addresses the review feedback on #24100:

  • Uses the shared common::backoff::ExponentialBackoff (from_millis(2).factor(250), capped at 30s), matching aws_s3/sqs, instead of a bespoke helper. Backoff resets on a successful connect.
  • Emits reconnection internal events: RedisConnectionErrorcomponent_errors_total (error_type=connection_failed) on connect/subscribe failure, and RedisConnectionEstablishedconnection_established_total on initial connect and recovery.
  • Adds a changelog fragment.

Also unifies the list data_type source onto the same shared ExponentialBackoff (removing its duplicate backoff_exponential) and makes its retry sleep shutdown-aware.

gibranbadrul and others added 2 commits July 18, 2026 21:54
…_type`

- Rework channel source to maintain a pubsub session that auto-reconnects
  and re-subscribes after Redis disconnects.
- Add shutdown-aware backoff and best-effort unsubscribe on exit.
- Log when the connection is re-established ("re-established and resubscribed").

Resolves vectordotdev#22615
Follow-up to the reconnecting pub/sub work:

- Replace the ad-hoc `backoff_exponential` helper with the shared
  `common::backoff::ExponentialBackoff` (from_millis(2).factor(250),
  capped at 30s), matching the strategy used by other reconnecting
  sources such as `aws_s3`/`sqs`. Backoff resets on a successful connect.
- Emit internal events for reconnection so operators can observe/alert:
  `RedisConnectionError` (increments `component_errors_total` with
  error_type=connection_failed) on connect/subscribe failure, and
  `RedisConnectionEstablished` (increments `connection_established_total`)
  on initial connect and recovery.
- Unify the `list` data_type source (`list.rs`) onto the same shared
  `ExponentialBackoff`, removing its duplicate `backoff_exponential`
  helper and making its retry sleep shutdown-aware.
- Add a changelog fragment.

Co-authored-by: Gibran <gibran.zaman@finaccel.co>
@artusmode
artusmode requested a review from a team as a code owner July 19, 2026 01:58
@github-actions github-actions Bot added the domain: sources Anything related to the Vector's sources label Jul 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your contribution! Before we can merge this PR, please sign our Contributor License Agreement.

To sign, copy and post the phrase below as a new comment on this PR.

Note: If the bot says your username was not found, the email used in your git commit may not be linked to your GitHub account. Fix this at github.com/settings/emails, then comment recheck to retry.


I have read the CLA Document and I hereby sign the CLA


1 out of 2 committers have signed the CLA.
✅ (gibranbadrul)[https://github.com/gibranbadrul]
@artusmode
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@datadog-vectordotdev

Copy link
Copy Markdown

Pipelines

⚠️ Warnings

🚦 1 Pipeline job failed

CLA Assistant | CLAAssistant   View in Datadog   GitHub Actions

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: aa85aeb | Docs | Give us feedback!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aa85aeb2f1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

loop {
// connect + SUBSCRIBE
let mut pubsub_conn =
match connect_and_subscribe(&client, &endpoint, &channel).await {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Race Redis reconnect attempts with shutdown

When the channel source is in the reconnect loop and a Redis connect/subscribe attempt stalls, for example against a black-holed TCP/TLS endpoint, this await is not raced with shutdown. A shutdown signal that arrives after the backoff completes or during the connect will not be observed until the Redis client/OS connect attempt returns, so the source misses graceful shutdown and Vector waits for the force-shutdown deadline. Please wrap connect_and_subscribe in a tokio::select! with the shutdown signal and/or apply a per-attempt timeout.

Useful? React with 👍 / 👎.

Comment thread src/sources/redis/list.rs
// `aws_s3`/`sqs`. Reset once a value is successfully received.
let mut backoff = ExponentialBackoff::from_millis(2)
.factor(250)
.max_delay(Duration::from_secs(30));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep Redis list retries capped at the previous 1s

For existing data_type = "list" configurations, this reused backoff now grows to 30 seconds after repeated Redis I/O errors. During a Redis outage the list source can reach that cap, and once Redis is back it may still wait up to 30 seconds before the next BLPOP/BRPOP; the removed helper capped retries at 1 second, so this unrelated list change is a significant recovery regression. Keep the list source's prior cap or avoid changing its retry policy while adding channel reconnects.

Useful? React with 👍 / 👎.

match end_reason {
SessionEnd::Shutdown | SessionEnd::DownstreamClosed => {
// shutting down cleanly, or downstream closed: stop for good.
let _ = pubsub_conn.unsubscribe(&channel).await;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid awaiting Redis unsubscribe during shutdown

When shutdown is selected while the Pub/Sub session is still connected, this branch now waits for Redis to acknowledge UNSUBSCRIBE before the source can exit. If Redis is slow or the TCP connection is half-open during shutdown, graceful shutdown can block until the force-shutdown deadline; the previous take_until(shutdown) path stopped immediately by dropping the connection. Since the component is already stopping, avoid a network round trip here or race it with the shutdown/force path.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: sources Anything related to the Vector's sources

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Redis doesn't resubscribe/reconnect to channel

2 participants