Commit Graph
307 Commits
Author SHA1 Message Date
c4770cde7c fix(error): detect READONLY errors from Lua scripts on read-only replicas (#3769)
When a Lua script containing a write command is executed against a
read-only replica in a Redis Cluster, the error may contain
"-READONLY You can't write against a read only replica" embedded
within a larger error message rather than starting with "READONLY ".

The existing code only checked for the "READONLY " prefix, missing
this format. This caused shouldRetry() and isReadOnlyError() to fail,
preventing automatic retry and connection pool cleanup.

The fix checks for the exact substring
"-READONLY You can't write against a read only replica" which is
specific enough to avoid false positives while catching the Lua
script error format.

Closes #2770

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-04-09 15:08:05 +03:00
BigskandGitHub cd984fae99 chore(ring): inline rendezvous hashing and remove external dependency (#3762)
* ring: remove external rendezvous dependency by inlining implementation

Replace usage of github.com/dgryski/go-rendezvous with an internal
implementation to eliminate the external dependency and avoid licence
propagation concerns.

The implementation preserves the exact hashing algorithm and behaviour:
- same hash combination: khash ^ nhash
- same mixing function (xorshift* variant)
- same node ordering semantics

No functional changes intended.

* Refactor TestRendezvous to remove randomString function

Replaced function with inline string generation for test cases.

* test: refactor RendezvousHash tests to use Ginkgo and Gomega

* test: improve RendezvousHash test for per-instance determinism and distribution balance

* test: enhance distribution verification in RendezvousHash tests
2026-04-07 10:26:18 +03:00
ofekshenawaandGitHub 73418596a3 feat(client): Add DoRaw and DoRawWriteTo for raw RESP protocol access (#3713)
* Add DoRaw and DoRawWriteTo for raw RESP protocol access

* fix augment comments

* Pipeline retry fix

* Fix Missing NoRetry check in cluster and ring retry loops
2026-03-23 17:35:59 +02:00
7c6b09e297 feat(options): add dial retry backoff function. (#3706)
* add dial retry backoff function.

* add readme

* add backoff to wordlist

* add logical consistency check

* fix(cluster): propagate DialerRetryBackoff to per-node clients

ClusterOptions.clientOptions() was not propagating DialerRetryBackoff,
causing the backoff function to be silently ignored when set on a cluster
client.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

---------

Co-authored-by: Nedyalko Dyakov <[email protected]>
Co-authored-by: Claude Sonnet 4.6 <[email protected]>
2026-03-19 20:45:20 +02:00
ofekshenawaandGitHub cd3949d1a0 fix: connection closure metrics and enable all metric groups by default (#3735)
* fix: connection closure metrics and enable all metric groups by default

This commit addresses three issues in the redisotel-native metrics implementation:

1. Fix connection closure metrics not appearing in dashboards
   - Root cause: CloseConn() in internal/pool/pool.go was not calling
     the metricConnectionClosedCallback when closing stale connections
   - Added callback invocation in CloseConn() to record 'stale' closures

2. Verify tracing and metrics compatibility
   - Added TestTracingAndMetricsCompatibility to document that
     redisotel (tracing via AddHook) and redisotel-native (metrics via
     SetOTelRecorder) can coexist without conflicts

3. Enable all metric groups by default
   - Changed default MetricGroups from connection-basic+resiliency
     to MetricGroupAll for comprehensive observability out of the box
2026-03-16 09:54:24 +02:00
6193e530d6 chore(docs): fix irrelevant docs links (#3724)
Co-authored-by: Olzhas Sabiyev <[email protected]>
2026-02-28 10:04:30 +02:00
475b50a948 fix(timeout): make dial timeout per-retry (#3705)
* Dial timeout is per-retry

Use dial timeout for each dial attempt, rather than
all attempts together.

* some tests

* additional tests

* use parent timeout so we can test our changes

---------

Co-authored-by: Nedyalko Dyakov <[email protected]>
2026-02-20 17:53:10 +02:00
Nedyalko DyakovandGitHub 3b155e9443 chore(go): update go version to 1.24 (#3714)
* chore(go): update go version to 1.24

* update readmes and ci workflows

* update dockerfile for proxy-fi-server

* address changed test behaviour

* address changed test behaviour
2026-02-20 10:00:33 +02:00
ee6e9dbf09 feat(otel): Add OpenTelemetry Native Metrics Support (#3637)
* First draft. One metric - command duration.

Signed-off-by: Elena Kolevska <[email protected]>

* Adds connection state metrics

Signed-off-by: Elena Kolevska <[email protected]>

* wip

Signed-off-by: Elena Kolevska <[email protected]>

* Add phase 1 metrics

* Add client api configurations

* remove redundent code

* refactor: move otel-metrics example to separate module

* refactor: move otel-metrics example to separate module

* remove internal test

* Resolve merge conflicts with upstream/master

* Fix linting issues

* Fix pool idle connection counter bug

* Add OTel performance benchmarking suite

* Improve perf compatison script

* Add phase 2,3 metrics

* Remove local benchmark tests

* Add new fields to tests

* Change db.client.connection.count and db.client.connection.pending_request metric type from UpAndDownCounter to Async gauge.

* fix golangci lint

* Add piplined commands metrics support

* Redesign otel init method

* Address comments

* Fix golangci-lint errors

* Fix passing nil pointer

* Add metric prefix to callbacks and atomic batch registration

* Add unique name for pool.name attr

* Fix unique pool name for pubsub

* Refactor all hardcoded OTel attribute strings to use constants

* Refactor all hardcoded OTel attribute strings to use constants

* extract metric names and pool names as constants, improve error handling

---------

Signed-off-by: Elena Kolevska <[email protected]>
Co-authored-by: Elena Kolevska <[email protected]>
2026-02-13 18:08:10 +02:00
b53f2b0c9d feat(sch): MaintNotifications for ClusterClient (#3643)
* [maintnotif] Cluster specific handlers (#3613)

* maint notification handlers for cluster messages

* unrelax all conns

* trigger ci on feature branches

* feat(maintnotif): lazy cluster topology reload (#3614)

* lazy cluster topology reload

* fix discrepancies between options structs

* Update osscluster_lazy_reload_test.go

Co-authored-by: Copilot <[email protected]>

* Update osscluster.go

Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Copilot <[email protected]>

* feat(e2e): mock maintnotif e2e tests (#3639)

* lazy cluster topology reload

* fix discrepancies between options structs

* Update osscluster_lazy_reload_test.go

Co-authored-by: Copilot <[email protected]>

* Update osscluster.go

Co-authored-by: Copilot <[email protected]>

* wip fault with mock proxy

* make lint happy

* fix linter issues

* faster tests with mocks

* linter once again

* add complex node test

* add ci e2e

* use correct redis container

* e2e fix

---------

Co-authored-by: Copilot <[email protected]>

* fix(retry): Add retry mechanism for NOREPLICAS error (#3647)

* fix(queuedNewConn): protect against nil context (#3649)

* fix(maintnotif): fix smigrated parser and add cluster state reload interval option (#3663)

* fix SMIGRATED parsing

* fix smigrated parser

* add ClusterStateReloadInterval to ClusterOptions

* fix tests

* set default cluster reload interval to 10s

* chore(lint): format

* feat(smigrated): new format & remember original host:port (#3697)

* lazy cluster topology reload

* fix discrepancies between options structs

* Update osscluster_lazy_reload_test.go

Co-authored-by: Copilot <[email protected]>

* Update osscluster.go

Co-authored-by: Copilot <[email protected]>

* wip fault with mock proxy

* make lint happy

* fix linter issues

* faster tests with mocks

* linter once again

* add complex node test

* add ci e2e

* use correct redis container

* e2e fix

* additional e2e tests

* fix data race

* fix random shard picker

* fix e2e tests

* fix for empty endpoint

* fix case when semaphore is full, but still need to check idle

* scenario tests

* create database from config

* wip

* feat(client): store original addrs for later use

* fix(notif): change smigrated notification

* fix(lint): fix linter

* fix(smigrated): use array

* fix(e2e): wip

* Update options.go

Co-authored-by: Copilot <[email protected]>

* Update redis.go

Co-authored-by: Copilot <[email protected]>

* fix(notif): if the conn has no original addr, trigger reload with first target

* chore(e2e): wip cluster e2e

* chore(e2e): fix nil pointer from e2e tests

* chore(e2e): fix tests and reports

* chore(e2e): proper logging in e2e

* chore(e2e): add pubsub in the tests as well

* chore(e2e): mockproxy fixes

* chore(e2e): mockproxy fixes

* chore(e2e): mockproxy fixes

* chore(e2e): mockproxy fixes v3

* stop background routines

* fix(e2e): tests

---------

Co-authored-by: Copilot <[email protected]>

* chore(docs): add example app (#3651)

* chore(lint): fmt

* chore(docs): improve docs

* chore(docs): update features.md

* chore(github): remove example

* chore(maintnotif): rename option and address pr comments

* fix(e2e): command runner should use client timeout

* chore(e2e): refactor tests

* fix(e2e): set default timeout to 90m

* fix(e2e): skip tests if proxy cannot be started

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: ofekshenawa <[email protected]>
Co-authored-by: Elena Kolevska <[email protected]>
2026-02-13 13:25:07 +02:00
a44932b17b fix(pool): fix wantConnQueue zombie elements and add comprehensive test coverage (#3680)
* discard zombie elements in wantConnQueue

* fix lint

---------

Co-authored-by: Nedyalko Dyakov <[email protected]>
2026-01-24 15:58:58 +02:00
5e807fccb0 chore(docs): add comprehensive documentation to set commands (#3642)
* Added documentation for explaining the methods responsibility

* Added link to each method doc

* Updated doc format

* Formatted code

* Formatted code

* Formatted code

---------

Co-authored-by: Nedyalko Dyakov <[email protected]>
2026-01-19 18:11:39 +02:00
cyningsunandGitHub 1bf873ed6a feat(pool): add ConnMaxLifetimeJitter to prevent connection thundering herd (#3666)
* add connection max lifetime jitter

* refactor calcConnExpiresAt
2026-01-15 17:01:41 +02:00
2b8d05ed37 chore(fmt): proper formatting (#3670)
* all: proper formatting

* .golangci.yml: add linter for format check

* ran `golangci-lint fmt`

---------

Co-authored-by: Nedyalko Dyakov <[email protected]>
2026-01-13 14:48:02 +02:00
cxljsandGitHub 254e65fb47 refactor(math): use Go1.21's built-in min/max function (#3656)
Signed-off-by: Xiaolong Chen <[email protected]>
2026-01-08 17:46:13 +02:00
Nedyalko DyakovandGitHub 452eb3d15f fix(queuedNewConn): protect against nil context (#3649) 2025-12-16 15:06:35 +02:00
ofekshenawaandGitHub 4edf494293 fix(retry): Add retry mechanism for NOREPLICAS error (#3647) 2025-12-10 18:14:05 +02:00
3aec3ddf9a chore(proto): use go 1.20 idiomatic string<->byte conversion (#3435)
As of Go 1.20, this is the idiomatic way to convert from Bytes to
String and vice-versa.

This updates `go.mod` to 1.20, builds have already been running on
1.23.x and 1.24.x since #3274.

Co-authored-by: Nedyalko Dyakov <[email protected]>
2025-12-05 13:10:00 +02:00
674c7b8695 chore(go): update go version to 1.21 (#3640)
* chore(go): update go version to 1.21

* chore(aggregators): make aggregators work with 1.21

* fix doctests

* address copilot comments

* use atomic bool for logic and/or aggregators

* Update .github/workflows/build.yml

Co-authored-by: ccoVeille <[email protected]>

* use stable/oldstable, 1.23 and 1.21

* fix versions in README

* add oldstable in wordlist

---------

Co-authored-by: ccoVeille <[email protected]>
2025-12-05 12:27:55 +02:00
ccoVeilleandGitHub eeea45c8f8 fix(logs): panic on nil error in handoffWorkerManager closeConnFromRequest (#3633) 2025-12-03 10:43:29 +02:00
ofekshenawaandGitHub 7a345ab467 Revert PR #3634 (Observability metrics phase1) (#3635) 2025-12-03 10:24:05 +02:00
Elena Kolevskaandofekshenawa 2a7725db63 Adds connection state metrics
Signed-off-by: Elena Kolevska <[email protected]>
2025-12-03 10:01:53 +02:00
Elena Kolevskaandofekshenawa d588c3ca71 First draft. One metric - command duration.
Signed-off-by: Elena Kolevska <[email protected]>
2025-12-03 10:00:09 +02:00
d4ae523eb8 fix(pool): correct turn management in putIdleConn to prevent connection leaks (#3626)
* fix(pool): prevent double freeTurn in queuedNewConn

This commit fixes a critical race condition where freeTurn() could be
called twice in the connection pool's queuedNewConn flow, causing turn
counter inconsistency.

Problem:
- When a new connection creation failed in queuedNewConn, both the
  defer handler and the dialing goroutine could call freeTurn()
- This led to turn counter underflow and queue length inconsistency

Solution:
- Modified putIdleConn to return a boolean indicating whether the
  caller needs to call freeTurn()
  - Returns true: connection was put back to pool, caller must free turn
  - Returns false: connection was delivered to a waiting request,
    turn will be freed by the receiving goroutine
- Updated queuedNewConn to only call freeTurn() when putIdleConn
  returns true
- Improved error handling flow in the dialing goroutine

Changes:
- putIdleConn now returns bool instead of void
- Added comprehensive documentation for putIdleConn behavior
- Refactored error handling in queuedNewConn goroutine
- Updated test cases to reflect correct turn state expectations

This ensures each turn is freed exactly once, preventing resource
leaks and maintaining correct queue state.

* fix: sync double freeturn bug fix and context calculation from upstream

Synced from https://github.com/redis/go-redis/tree/ndyakov/freeturn-fix

Changes include:
- Add comprehensive tests for double freeTurn bug detection
- Improve context timeout calculation using min(remaining time, DialTimeout)
- Prevent goroutines from waiting longer than necessary

Co-authored-by: Nedyalko Dyakov <[email protected]>
Co-authored-by: Copilot <[email protected]>

---------

Co-authored-by: Nedyalko Dyakov <[email protected]>
Co-authored-by: Nedyalko Dyakov <[email protected]>
Co-authored-by: Copilot <[email protected]>
2025-12-01 12:20:58 +02:00
f711eb0f62 feat(cluster): Implement Request and Response Policy Based Routing in Cluster Mode (#3422)
* Add search module builders and tests (#1)

* Add search module builders and tests

* Add tests

* Use builders and Actions in more clean way

* Update search_builders.go

Co-authored-by: Nedyalko Dyakov <[email protected]>

* Update search_builders.go

Co-authored-by: Nedyalko Dyakov <[email protected]>

* Apply suggestions from code review

Co-authored-by: Nedyalko Dyakov <[email protected]>

* feat(routing): add internal request/response policy enums

* feat: load the policy table in cluster client (#4)

* feat: load the policy table in cluster client

* Remove comments

* modify Tips and command pplicy in commandInfo (#5)

* centralize cluster command routing in osscluster_router.go and refactor osscluster.go (#6)

* centralize cluster command routing in osscluster_router.go and refactor osscluster.go

* enalbe ci on all branches

* Add debug prints

* Add debug prints

* FIX: deal with nil policy

* FIX: fixing clusterClient process

* chore(osscluster): simplify switch case

* wip(command): ai generated clone method for commands

* feat: implement response aggregator for Redis cluster commands

* feat: implement response aggregator for Redis cluster commands

* fix: solve concurrency errors

* fix: solve concurrency errors

* return MaxRedirects settings

* remove locks from getCommandPolicy

* Handle MOVED errors more robustly, remove cluster reloading at exectutions, ennsure better routing

* Fix: supports Process hook test

* Fix: remove response aggregation for single shard commands

* Add more preformant type conversion for Cmd type

* Add router logic into processPipeline

---------

Co-authored-by: Nedyalko Dyakov <[email protected]>

* remove thread debugging code

* remove thread debugging code && reject commands with policy that cannot be used in pipeline

* refactor processPipline and cmdType enum

* remove FDescribe from cluster tests

* Add tests

* fix aggregation test

* fix mget test

* fix mget test

* remove aggregateKeyedResponses

* added scaffolding for the req-resp manager

* added default policies for the search commands

* split command map into module->command

* cleanup, added logic to refresh the cache

* added reactive cache refresh

* revert cluster refresh

* fixed lint

* addresed first batch of comments

* rewrote aggregator implementations with atomic for native or nearnative primitives

* addressed more comments, fixed lint

* added batch aggregator operations

* fixed lint

* updated batch aggregator, fixed extractcommandvalue

* fixed lint

* added batching to aggregateResponses

* fixed deadlocks

* changed aggregator logic, added error params

* added preemptive return to the aggregators

* more work on the aggregators

* updated and and or aggregators

* fixed lint

* added configurable policy resolvers

* slight refactor

* removed the interface, slight refactor

* change func signature from cmdName to cmder

* added nil safety assertions

* few small refactors

* added read only policies

* removed leftover prints

* Rebased to master, resolved comnflicts

* fixed lint

* updated gha

* fixed tests, minor consistency refactor

* preallocated simple errors

* changed numeric aggregators to use float64

* speculative test fix

* Update command.go

Co-authored-by: Nedyalko Dyakov <[email protected]>

* Update main_test.go

Co-authored-by: Nedyalko Dyakov <[email protected]>

* Add static shard picker

* Fix nil value handling in command aggregation

* Modify the Clone method to return a shallow copy

* Add clone method to digest command

* Optimize keyless command routing to respect ShardPicker policy

* Remove MGET references

* Fix MGET aggregation to map individual values to keys across shards

* Add clone method to hybrid search commands

* Undo changes in route keyless test

* remove comments

* Add test for DisableRoutingPolicies option

* Add Routing Policies Comprehensive Test Suite and Fix multi keyed aggregation for different step

---------

Co-authored-by: Nedyalko Dyakov <[email protected]>
Co-authored-by: Nedyalko Dyakov <[email protected]>
Co-authored-by: Hristo Temelski <[email protected]>
2025-11-28 11:46:23 +02:00
Nedyalko DyakovandGitHub 63908223ca fix(time): remove cached time optimization (#3611) 2025-11-24 15:18:34 +02:00
Nedyalko DyakovandGitHub 5b0b228a37 chore(release): v9.17.0 (#3604)
* update release notes

* update readme

* update version number

* cleanup release notes

* fix checkMinIdle
2025-11-19 19:53:02 +02:00
6c24f600de feat(errors): Introduce typed errors (#3602)
* typed errors

* add error documentation

* backwards compatibility

* update readme, remove Is methods

* Update internal/proto/redis_errors.go

Co-authored-by: Copilot <[email protected]>

* Update internal/proto/redis_errors.go

Co-authored-by: Copilot <[email protected]>

* support error wrapping for io and context errors

* use unwrapping of errors in push for consistency

* add common error types

* fix test

* fix flaky test

* add comments in the example

---------

Co-authored-by: Copilot <[email protected]>
2025-11-19 17:31:54 +02:00
042610b79d fix(conn): conn to have state machine (#3559)
* wip

* wip, used and unusable states

* polish state machine

* correct handling OnPut

* better errors for tests, hook should work now

* fix linter

* improve reauth state management. fix tests

* Update internal/pool/conn.go

Co-authored-by: Copilot <[email protected]>

* Update internal/pool/conn.go

Co-authored-by: Copilot <[email protected]>

* better timeouts

* empty endpoint handoff case

* fix handoff state when queued for handoff

* try to detect the deadlock

* try to detect the deadlock x2

* delete should be called

* improve tests

* fix mark on uninitialized connection

* Update internal/pool/conn_state_test.go

Co-authored-by: Copilot <[email protected]>

* Update internal/pool/conn_state_test.go

Co-authored-by: Copilot <[email protected]>

* Update internal/pool/pool.go

Co-authored-by: Copilot <[email protected]>

* Update internal/pool/conn_state.go

Co-authored-by: Copilot <[email protected]>

* Update internal/pool/conn.go

Co-authored-by: Copilot <[email protected]>

* fix error from copilot

* address copilot comment

* fix(pool): pool performance  (#3565)

* perf(pool): replace hookManager RWMutex with atomic.Pointer and add predefined state slices

- Replace hookManager RWMutex with atomic.Pointer for lock-free reads in hot paths
- Add predefined state slices to avoid allocations (validFromInUse, validFromCreatedOrIdle, etc.)
- Add Clone() method to PoolHookManager for atomic updates
- Update AddPoolHook/RemovePoolHook to use copy-on-write pattern
- Update all hookManager access points to use atomic Load()

Performance improvements:
- Eliminates RWMutex contention in Get/Put/Remove hot paths
- Reduces allocations by reusing predefined state slices
- Lock-free reads allow better CPU cache utilization

* perf(pool): eliminate mutex overhead in state machine hot path

The state machine was calling notifyWaiters() on EVERY Get/Put operation,
which acquired a mutex even when no waiters were present (the common case).

Fix: Use atomic waiterCount to check for waiters BEFORE acquiring mutex.
This eliminates mutex contention in the hot path (Get/Put operations).

Implementation:
- Added atomic.Int32 waiterCount field to ConnStateMachine
- Increment when adding waiter, decrement when removing
- Check waiterCount atomically before acquiring mutex in notifyWaiters()

Performance impact:
- Before: mutex lock/unlock on every Get/Put (even with no waiters)
- After: lock-free atomic check, only acquire mutex if waiters exist
- Expected improvement: ~30-50% for Get/Put operations

* perf(pool): use predefined state slices to eliminate allocations in hot path

The pool was creating new slice literals on EVERY Get/Put operation:
- popIdle(): []ConnState{StateCreated, StateIdle}
- putConn(): []ConnState{StateInUse}
- CompareAndSwapUsed(): []ConnState{StateIdle} and []ConnState{StateInUse}
- MarkUnusableForHandoff(): []ConnState{StateInUse, StateIdle, StateCreated}

These allocations were happening millions of times per second in the hot path.

Fix: Use predefined global slices defined in conn_state.go:
- validFromInUse
- validFromCreatedOrIdle
- validFromCreatedInUseOrIdle

Performance impact:
- Before: 4 slice allocations per Get/Put cycle
- After: 0 allocations (use predefined slices)
- Expected improvement: ~30-40% reduction in allocations and GC pressure

* perf(pool): optimize TryTransition to reduce atomic operations

Further optimize the hot path by:
1. Remove redundant GetState() call in the loop
2. Only check waiterCount after successful CAS (not before loop)
3. Inline the waiterCount check to avoid notifyWaiters() call overhead

This reduces atomic operations from 4-5 per Get/Put to 2-3:
- Before: GetState() + CAS + waiterCount.Load() + notifyWaiters mutex check
- After: CAS + waiterCount.Load() (only if CAS succeeds)

Performance impact:
- Eliminates 1-2 atomic operations per Get/Put
- Expected improvement: ~10-15% for Get/Put operations

* perf(pool): add fast path for Get/Put to match master performance

Introduced TryTransitionFast() for the hot path (Get/Put operations):
- Single CAS operation (same as master's atomic bool)
- No waiter notification overhead
- No loop through valid states
- No error allocation

Hot path flow:
1. popIdle(): Try IDLE → IN_USE (fast), fallback to CREATED → IN_USE
2. putConn(): Try IN_USE → IDLE (fast)

This matches master's performance while preserving state machine for:
- Background operations (handoff/reauth use UNUSABLE state)
- State validation (TryTransition still available)
- Waiter notification (AwaitAndTransition for blocking)

Performance comparison per Get/Put cycle:
- Master: 2 atomic CAS operations
- State machine (before): 5 atomic operations (2.5x slower)
- State machine (after): 2 atomic CAS operations (same as master!)

Expected improvement: Restore to baseline ~11,373 ops/sec

* combine cas

* fix linter

* try faster approach

* fast semaphore

* better inlining for hot path

* fix linter issues

* use new semaphore in auth as well

* linter should be happy now

* add comments

* Update internal/pool/conn_state.go

Co-authored-by: Copilot <[email protected]>

* address comment

* slight reordering

* try to cache time if for non-critical calculation

* fix wrong benchmark

* add concurrent test

* fix benchmark report

* add additional expect to check output

* comment and variable rename

---------

Co-authored-by: Copilot <[email protected]>

* initConn sets IDLE state

- Handle unexpected conn state changes

* fix precision of time cache and usedAt

* allow e2e tests to run longer

* Fix broken initialization of idle connections

* optimize push notif

* 100ms -> 50ms

* use correct timer for last health check

* verify pass auth on conn creation

* fix assertion

* fix unsafe test

* fix benchmark test

* improve remove conn

* re doesn't support requirepass

* wait more in e2e test

* flaky test

* add missed method in interface

* fix test assertions

* silence logs and faster hooks manager

* address linter comment

* fix flaky test

* use read instad of control

* use pool size for semsize

* CAS instead of reading the state

* preallocate errors and states

* preallocate state slices

* fix flaky test

* fix fast semaphore that could have been starved

* try to fix the semaphore

* should properly notify the waiters

- this way a waiter that timesout at the same time
a releaser is releasing, won't throw token. the releaser
will fail to notify and will pick another waiter.

this hybrid approach should be faster than channels and maintains FIFO

* waiter may double-release (if closed/times out)

* priority of operations

* use simple approach of fifo waiters

* use simple channel based semaphores

* address linter and tests

* remove unused benchs

* change log message

* address pr comments

* address pr comments

* fix data race

---------

Co-authored-by: Copilot <[email protected]>
2025-11-11 17:38:29 +02:00
ae5434ce66 feat(pool): Improve success rate of new connections (#3518)
* async create conn

* update default values and testcase

* fix comments

* fix data race

* remove context.WithoutCancel, which is a function introduced in Go 1.21

* fix TestDialerRetryConfiguration/DefaultDialerRetries, because tryDial are likely done in async flow

* change to share failed to delivery connection to other waiting

* remove chinese comment

* fix: optimize WantConnQueue benchmarks to prevent memory exhaustion

- Fix BenchmarkWantConnQueue_Dequeue timeout issue by limiting pre-population
- Use object pooling in BenchmarkWantConnQueue_Enqueue to reduce allocations
- Optimize BenchmarkWantConnQueue_EnqueueDequeue with reusable wantConn pool
- Prevent GitHub Actions benchmark failures due to excessive memory usage

Before: BenchmarkWantConnQueue_Dequeue ran for 11+ minutes and was killed
After: All benchmarks complete in ~8 seconds with consistent performance

* format

* fix turn leaks

---------

Co-authored-by: Nedyalko Dyakov <[email protected]>
Co-authored-by: Hristo Temelski <[email protected]>
2025-10-30 19:21:12 +02:00
9c77386b08 chore(tests): internal/proto/peek_push_notification_test : Refactor test helpers to… (#3563)
* internal/proto/peek_push_notification_test : Refactor test helpers to use fmt.Fprintf for buffers

Replaced buf.WriteString(fmt.Sprintf(...)) with fmt.Fprintf or fmt.Fprint in test helper functions for improved clarity and efficiency. This change affects push notification and RESP3 test utilities.

* peek_push_notification_test: revert prev formatting

* all: replace buf.WriteString with fmt.FprintF for consistency

---------

Co-authored-by: Nedyalko Dyakov <[email protected]>
2025-10-28 11:41:45 +02:00
a15e76394c fix(pool): Pool ReAuth should not interfere with handoff (#3547)
* fix(pool): wip, pool reauth should not interfere with handoff

* fix credListeners map

* fix race in tests

* better conn usable timeout

* add design decision comment

* few small improvements

* update marked as queued

* add Used to clarify the state of the conn

* rename test

* fix(test): fix flaky test

* lock inside the listeners collection

* address pr comments

* Update internal/auth/cred_listeners.go

Co-authored-by: Copilot <[email protected]>

* Update internal/pool/buffer_size_test.go

Co-authored-by: Copilot <[email protected]>

* wip refactor entraid

* fix maintnotif pool hook

* fix mocks

* fix nil listener

* sync and async reauth based on conn lifecycle

* be able to reject connection OnGet

* pass hooks so the tests can observe reauth

* give some time for the background to execute commands

* fix tests

* only async reauth

* Update internal/pool/pool.go

Co-authored-by: Copilot <[email protected]>

* Update internal/auth/streaming/pool_hook.go

Co-authored-by: Copilot <[email protected]>

* Update internal/pool/conn.go

Co-authored-by: Copilot <[email protected]>

* chore(redisotel): use metric.WithAttributeSet to avoid copy (#3552)

In order to improve performance replace `WithAttributes` with `WithAttributeSet`.
This avoids the slice allocation and copy that is done in `WithAttributes`.

For more information see https://github.com/open-telemetry/opentelemetry-go/blob/v1.38.0/metric/instrument.go#L357-L376

* chore(docs): explain why MaxRetries is disabled for ClusterClient (#3551)

Co-authored-by: Nedyalko Dyakov <[email protected]>

* exponential backoff

* address pr comments

* address pr comments

* remove rlock

* add some comments

* add comments

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Warnar Boekkooi <[email protected]>
Co-authored-by: Justin <[email protected]>
2025-10-22 12:45:30 +03:00
3ad9f9cb23 fix: add missing error variable for non-unix build constraints (#3538)
* fix: add missing error variable for non-unix build constraints

* chore: name "_" for unused parameters

---------

Co-authored-by: Elena Kolevska <[email protected]>
2025-09-29 09:35:04 +03:00
75ddeb3d5a feat(e2e-testing): maintnotifications e2e and refactor (#3526)
* e2e wip

* cleanup

* remove unused fault injector mock

* errChan in test

* remove log messages tests

* cleanup log messages

* s/hitless/maintnotifications/

* fix moving when none

* better logs

* test with second client after action has started

* Fixes

Signed-off-by: Elena Kolevska <[email protected]>

* Test fix

Signed-off-by: Elena Kolevska <[email protected]>

* feat(e2e-test): Extended e2e tests

* imroved e2e test resiliency

---------

Signed-off-by: Elena Kolevska <[email protected]>
Co-authored-by: Elena Kolevska <[email protected]>
Co-authored-by: Elena Kolevska <[email protected]>
Co-authored-by: Hristo Temelski <[email protected]>
2025-09-26 19:17:09 +03:00
0ef6d0727d feat: RESP3 notifications support & Hitless notifications handling [CAE-1088] & [CAE-1072] (#3418)
- Adds support for handling push notifications with RESP3. 
- Using this support adds handlers for hitless upgrades.

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Hristo Temelski <[email protected]>
2025-09-10 22:18:01 +03:00
cxljsandGitHub e07f55bed1 chore(buffers): Set the default read/write buffer size of Redis connection to 32KiB (#3483)
* update README.md

Signed-off-by: Xiaolong Chen <[email protected]>

* typo: 0.5MiB -> 256KiB

Signed-off-by: Xiaolong Chen <[email protected]>

* Set the default read/write buffer size of Redis connection to 32KiB

Signed-off-by: Xiaolong Chen <[email protected]>

---------

Signed-off-by: Xiaolong Chen <[email protected]>
2025-08-18 20:04:55 +03:00
Nedyalko DyakovandGitHub 94cfffa417 fix(options): Add buffer sizes to failover. Update README (#3468)
* fix(options): Add buffer sizes to failover. Update README

* fix(spellcheck): add KiB in wordlist

* fix(comment): fix defaul value in comment

* fixes #3465
2025-08-11 16:01:24 +03:00
6a48d3fec1 feat: recover addIdleConn may occur panic (#2445)
* feat: recover addIdleConn may occur panic

Signed-off-by: monkey92t <[email protected]>

* fix test race

Signed-off-by: monkey92t <[email protected]>

---------

Signed-off-by: monkey92t <[email protected]>
Co-authored-by: Nedyalko Dyakov <[email protected]>
2025-08-05 15:31:58 +03:00
ofekshenawaandGitHub 1eed165f9d feat(proto): add configurable buffer sizes for Redis connections (#3453)
* add configurable buffer sizes for Redis connections

* add MiB to wordlist

* Add description for buffer size parameter
2025-08-04 09:16:54 +03:00
4ac591c7c4 Set correct cluster slot for scan commands, similarly to Java's Jedis client (#2623)
- At present, the `scan` command is dispatched to a random slot.
- As far as I can tell, the scanX family of commands are not cluster aware (e.g. don't redirect the client to the correct slot).
- You can see [here](https://github.com/redis/jedis/blob/869dc0bb6625b85c8bf15bf1361bde485a304338/src/main/java/redis/clients/jedis/ShardedCommandObjects.java#L101), the Jedis client calling `processKey` on the match argument, and this is what this PR also does.

We've had this patch running in production, and it seems to work well for us.

For further thought:
- Continuing looking at other Redis clients (e.g. Jedis), they outright [reject as invalid](https://github.com/redis/jedis/blob/869dc0bb6625b85c8bf15bf1361bde485a304338/src/main/java/redis/clients/jedis/ShardedCommandObjects.java#L98) any scan command that does not include a hash-tag. Presumably this has the advantage of users not being surprised when their scan produces no results when a random server is picked.
- Perhaps it would be sensible for go-redis to do the same also?

Co-authored-by: Nedyalko Dyakov <[email protected]>
2025-06-24 13:43:03 +03:00
WeizhongTuandGitHub 7d97cc1c59 feat: optimize connection pool waitTurn (#3412) 2025-06-20 12:07:14 +03:00
eb40ac8328 perf: reduce unnecessary memory allocation (#3399)
Signed-off-by: fukua95 <[email protected]>
Co-authored-by: Nedyalko Dyakov <[email protected]>
2025-06-09 11:59:58 +03:00
Nedyalko DyakovandGitHub 86d418f940 feat: Introducing StreamingCredentialsProvider for token based authentication (#3320)
* wip

* update documentation

* add streamingcredentialsprovider in options

* fix: put back option in pool creation

* add package level comment

* Initial re authentication implementation

Introduces the StreamingCredentialsProvider as the CredentialsProvider
with the highest priority.

TODO: needs to be tested

* Change function type name

Change CancelProviderFunc to UnsubscribeFunc

* add tests

* fix race in tests

* fix example tests

* wip, hooks refactor

* fix build

* update README.md

* update wordlist

* update README.md

* refactor(auth): early returns in cred listener

* fix(doctest): simulate some delay

* feat(conn): add close hook on conn

* fix(tests): simulate start/stop in mock credentials provider

* fix(auth): don't double close the conn

* docs(README): mark streaming credentials provider as experimental

* fix(auth): streamline auth err proccess

* fix(auth): check err on close conn

* chore(entraid): use the repo under redis org
2025-05-27 16:25:20 +03:00
c149644da7 Unit test for pool acquisition timeout (#3381)
Co-authored-by: Nedyalko Dyakov <[email protected]>
2025-05-19 19:46:19 +03:00
fukua95andGitHub 3af2cc5783 chore: optimize function ReplaceSpaces (#3383)
* chore: optimize function `ReplaceSpaces`

Signed-off-by: fukua95 <[email protected]>

* trigger CI again because the bug of docker

Signed-off-by: fukua95 <[email protected]>

* trigger CI again because the bug of docker

Signed-off-by: fukua95 <[email protected]>

---------

Signed-off-by: fukua95 <[email protected]>
2025-05-19 19:21:17 +03:00
Amir SalehiandGitHub 43e7fb5eef test(util): add unit tests for Atoi, ParseInt, ParseUint, and ParseFloat (#3377) 2025-05-15 14:53:54 +03:00
ofekshenawaandGitHub 42c32846e6 utils: export ParseFloat and MustParseFloat wrapping internal utils (#3371)
* utils: expose ParseFloat via new public utils package

* add tests for special float values in vector search
2025-05-09 12:24:36 +03:00
8ba559ca5d feat: add connection waiting statistics (#2804)
Co-authored-by: ofekshenawa <[email protected]>
2025-05-07 15:54:26 +03:00
LINKIWIandGitHub 9762559c75 Bound connection pool background dials to configured dial timeout (#3089) 2025-03-24 15:45:43 +02:00
ebe11d06ca feat: Enable CI for Redis CE 8.0 (#3274)
* chore: extract benchmark tests

* wip

* enable pubsub tests

* enable ring tests

* stop tests with build redis from source

* start all tests

* mix of makefile and action

* add sentinel configs

* fix example test

* stop debug on re

* wip

* enable gears for redis 7.2

* wip

* enable sentinel, they are expected to fail

* fix: linter configuration

* chore: update re versions

* return older redis enterprise version

* add basic codeql

* wip: increase timeout, focus only sentinel tests

* sentinels with docker network host

* enable all tests

* fix flanky test

* enable example tests

* tidy docker compose

* add debug output

* stop shutingdown masters

* don't test sentinel for re

* skip unsuported addscores

* Update README

bump go version in CI

* Update README.md

Co-authored-by: Copilot <[email protected]>

* Update CONTRIBUTING.md

add information about new test setup

---------

Co-authored-by: Copilot <[email protected]>
2025-02-28 12:49:00 +02:00