Skip to content

fix(pubsub): prevent double reconnect in releaseConn#3833

Merged
ndyakov merged 1 commit into
redis:masterfrom
cxljs:fix/pubsub-double-reconnect
May 29, 2026
Merged

fix(pubsub): prevent double reconnect in releaseConn#3833
ndyakov merged 1 commit into
redis:masterfrom
cxljs:fix/pubsub-double-reconnect

Conversation

@cxljs

@cxljs cxljs commented May 28, 2026

Copy link
Copy Markdown
Contributor

When a connection is both not usable and has a bad conn error, releaseConn would call reconnect twice — first establishing a new connection, then immediately closing it to create another. Add early return after the first reconnect to avoid the wasted connection.


Note

Low Risk
Single control-flow guard in pub/sub connection release; no API or security surface changes.

Overview
Fixes a bug in PubSub.releaseConn where an unusable or handoff connection could trigger reconnect twice in one call—once for !IsUsable() / ShouldHandoff(), and again if isBadConn(err, …) was also true.

Adds an early return after the first reconnect so a bad-connection error on the same release path does not immediately tear down and reopen the connection again.

Reviewed by Cursor Bugbot for commit 02ebca1. Bugbot is set up for automated code reviews on this repo. Configure here.

When a connection is both not usable and has a bad conn error,
releaseConn would call reconnect twice — first establishing a new
connection, then immediately closing it to create another. Add early
return after the first reconnect to avoid the wasted connection.

@ndyakov ndyakov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should not happen, but makes sense to have this.

Comment thread pubsub.go
@ndyakov ndyakov added the bug label May 29, 2026
@ndyakov
ndyakov merged commit 65d6abd into redis:master May 29, 2026
40 checks passed
@cxljs

cxljs commented May 29, 2026

Copy link
Copy Markdown
Contributor Author

This should not happen, but makes sense to have this.

Thanks for the review! To be honest, I caught this potential edge case just by reading the code and found it really difficult to write a stable reproduction test. I wasn't entirely sure if it could be triggered in practice, so I submitted this as a defensive fix.

rohitkumarankam pushed a commit to rohitkumarankam/forgejo that referenced this pull request Jun 11, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [github.com/redis/go-redis/v9](https://github.com/redis/go-redis) | `v9.20.0` → `v9.20.1` | ![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2fredis%2fgo-redis%2fv9/v9.20.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2fredis%2fgo-redis%2fv9/v9.20.0/v9.20.1?slim=true) |

---

### Release Notes

<details>
<summary>redis/go-redis (github.com/redis/go-redis/v9)</summary>

### [`v9.20.1`](https://github.com/redis/go-redis/releases/tag/v9.20.1): 9.20.1

[Compare Source](redis/go-redis@v9.20.0...v9.20.1)

This is a patch release containing bug fixes only. There are no new features or breaking changes; upgrading from 9.20.0 is a drop-in replacement.

#### 🚀 Highlights

##### RESP3 pub/sub message loss fixed

`PeekPushNotificationName` previously inspected only the bytes already buffered by `bufio`, so when a push frame header straddled a buffer fill boundary it could return a **truncated** notification name (e.g. `"messa"` instead of `"message"`). The push processor then mis-routed the frame and `ReadReply` silently dropped it, causing intermittent RESP3 pub/sub message loss. The peek now grows its window (36 bytes → up to 4 KiB) and reads more from the connection until the header is complete, cleanly separating incomplete prefixes from corrupt frames (including overflow-safe bulk-length handling). Fixes [#&#8203;3839](redis/go-redis#3839).

([#&#8203;3842](redis/go-redis#3842)) by [@&#8203;ndyakov](https://github.com/ndyakov)

#### 🐛 Bug Fixes

- **RESP3 push peeking**: `PeekPushNotificationName` no longer returns a truncated notification name when a push frame header spans a buffer boundary, preventing silent RESP3 pub/sub message loss (fixes [#&#8203;3839](redis/go-redis#3839)) ([#&#8203;3842](redis/go-redis#3842)) by [@&#8203;ndyakov](https://github.com/ndyakov)
- **`FT.HYBRID` vector params**: Vector data is now always sent via `PARAMS` with auto-generated param names (`__vector_param_N`, with collision avoidance) when `VectorParamName` is omitted, since Redis no longer accepts inline vector blobs; the `FTHybridOptions.Params` map is no longer mutated, so the same options struct can be reused across calls ([#&#8203;3844](redis/go-redis#3844)) by [@&#8203;ndyakov](https://github.com/ndyakov)
- **`CLUSTER SHARDS` forward compatibility**: Unknown shard- and node-level attributes in the `CLUSTER SHARDS` reply are now skipped via `DiscardNext()` instead of erroring, so clients keep working when the server introduces new fields ([#&#8203;3843](redis/go-redis#3843)) by [@&#8203;madolson](https://github.com/madolson)
- **PubSub double reconnect**: `PubSub.releaseConn` no longer reconnects twice when a connection is both unusable (or pending handoff) and reports a bad-connection error, avoiding a wasted connection establish-then-close cycle ([#&#8203;3833](redis/go-redis#3833)) by [@&#8203;cxljs](https://github.com/cxljs)

#### 👥 Contributors

We'd like to thank all the contributors who worked on this release!

[@&#8203;cxljs](https://github.com/cxljs), [@&#8203;madolson](https://github.com/madolson), [@&#8203;ndyakov](https://github.com/ndyakov)

***

**Full Changelog**: <redis/go-redis@v9.20.0...v9.20.1>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 12:00 AM and 03:59 AM (`* 0-3 * * *`)
- Automerge
  - Between 12:00 AM and 03:59 AM (`* 0-3 * * *`)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMTQuNSIsInVwZGF0ZWRJblZlciI6IjQzLjIxNC41IiwidGFyZ2V0QnJhbmNoIjoiZm9yZ2VqbyIsImxhYmVscyI6WyJkZXBlbmRlbmN5LXVwZ3JhZGUiLCJ0ZXN0L25vdC1uZWVkZWQiXX0=-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/13061
Reviewed-by: Mathieu Fenniak <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants