1
0
mirror of https://github.com/redis/go-redis.git synced 2025-09-07 07:47:24 +03:00
Commit Graph

161 Commits

Author SHA1 Message Date
Nedyalko Dyakov
ded98eccb1 address comments 2025-08-19 15:56:48 +03:00
Nedyalko Dyakov
5649ffb314 feat(hitless): Introduce handlers for hitless upgrades
This commit includes all the work on hitless upgrades with the addition
of:

- Pubsub Pool
- Examples
- Refactor of push
- Refactor of pool (using atomics for most things)
- Introducing of hooks in pool
2025-08-18 22:14:06 +03:00
Nedyalko Dyakov
36f9f58c67 Merge branch 'master' into ndyakov/CAE-1088-resp3-notification-handlers 2025-08-18 22:11:06 +03:00
cxljs
e07f55bed1 chore(buffers): Set the default read/write buffer size of Redis connection to 32KiB (#3483)
* update README.md

Signed-off-by: Xiaolong Chen <fukua95@gmail.com>

* typo: 0.5MiB -> 256KiB

Signed-off-by: Xiaolong Chen <fukua95@gmail.com>

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

Signed-off-by: Xiaolong Chen <fukua95@gmail.com>

---------

Signed-off-by: Xiaolong Chen <fukua95@gmail.com>
2025-08-18 20:04:55 +03:00
cxljs
97817108dd Set the read/write buffer size of the sentinel client to 4KiB (#3476)
Signed-off-by: Xiaolong Chen <fukua95@gmail.com>
2025-08-14 15:48:45 +03:00
Nedyalko Dyakov
422779ba9f Merge remote-tracking branch 'origin/master' into ndyakov/CAE-1088-resp3-notification-handlers 2025-08-12 19:38:11 +03:00
ofekshenawa
436979f5c7 feat(options): Clean failing timeout implementation (#3472)
* Fix hard code of failing timeout

1. if not set failing time limit, default is 15 seconds.

* feat: Complete configurable FailingTimeoutSeconds implementation

---------

Co-authored-by: Shino Wu <shino_wu@trendmicro.com>
2025-08-12 14:08:28 +03:00
Nedyalko Dyakov
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
cxljs
375fa5d083 chore(doc): improve code readability (#3446)
- replace two similar functions `appendUniqueNode` and `appendIfNotExists` with a generic function.

- simplify the implementation of the `get` method in `clusterNodes`

- keep the member name `_generation` of `clusterNodes` consistent with other types.

- rename a data member `_masterAddr` to `masterAddr`.

Signed-off-by: Xiaolong Chen <fukua95@gmail.com>
2025-08-04 17:22:16 +03:00
Nedyalko Dyakov
72c24d59f4 Merge branch 'master' into ndyakov/CAE-1088-resp3-notification-handlers 2025-07-22 14:07:42 +03:00
Julien Riou
162c3fbf47 feat: Add "skip_verify" to Sentinel (#3428)
Same as 3d4310ae but for FailoverOptions.

Signed-off-by: Julien Riou <julien@riou.xyz>
2025-07-22 12:49:22 +03:00
cxljs
90923b3eb1 fix: errors.Join requires Go 1.20 or later (#3442)
Signed-off-by: Xiaolong Chen <fukua95@gmail.com>
2025-07-22 12:45:41 +03:00
Nedyalko Dyakov
84123b1331 refactor(push): completly change the package structure 2025-07-05 02:52:40 +03:00
Nedyalko Dyakov
5972b4c23f refactor: move all push notification logic to root package and remove adapters
Consolidate all push notification handling logic in the root package to eliminate
adapters and simplify the architecture. This provides direct access to concrete
types without any intermediate layers or type conversions.

Key Changes:

1. Moved Core Types to Root Package:
   - Moved Registry, Processor, VoidProcessor to push_notifications.go
   - Moved all push notification constants to root package
   - Removed internal/pushnotif package dependencies
   - Direct implementation without internal abstractions

2. Eliminated All Adapters:
   - Removed handlerAdapter that bridged internal and public interfaces
   - Removed voidProcessorAdapter for void processor functionality
   - Removed convertInternalToPublicContext conversion functions
   - Direct usage of concrete types throughout

3. Simplified Architecture:
   - PushNotificationHandlerContext directly implemented in root package
   - PushNotificationHandler directly implemented in root package
   - Registry, Processor, VoidProcessor directly in root package
   - No intermediate layers or type conversions needed

4. Direct Type Usage:
   - GetClusterClient() returns *ClusterClient directly
   - GetSentinelClient() returns *SentinelClient directly
   - GetRegularClient() returns *Client directly
   - GetPubSub() returns *PubSub directly
   - No interface casting or type assertions required

5. Updated All Integration Points:
   - Updated redis.go to use direct types
   - Updated pubsub.go to use direct types
   - Updated sentinel.go to use direct types
   - Removed all internal/pushnotif imports
   - Simplified context creation and usage

6. Core Implementation in Root Package:
   ```go
   // Direct implementation - no adapters needed
   type Registry struct {
       handlers  map[string]PushNotificationHandler
       protected map[string]bool
   }

   type Processor struct {
       registry *Registry
   }

   type VoidProcessor struct{}
   ```

7. Handler Context with Concrete Types:
   ```go
   type PushNotificationHandlerContext interface {
       GetClusterClient() *ClusterClient    // Direct concrete type
       GetSentinelClient() *SentinelClient  // Direct concrete type
       GetRegularClient() *Client           // Direct concrete type
       GetPubSub() *PubSub                  // Direct concrete type
   }
   ```

8. Comprehensive Test Suite:
   - Added push_notifications_test.go with full test coverage
   - Tests for Registry, Processor, VoidProcessor
   - Tests for HandlerContext with concrete type access
   - Tests for all push notification constants
   - Validates all functionality works correctly

9. Benefits:
   - Eliminated complex adapter pattern
   - Removed unnecessary type conversions
   - Simplified codebase with direct type usage
   - Better performance without adapter overhead
   - Cleaner architecture with single source of truth
   - Enhanced developer experience with direct access

10. Architecture Simplification:
    Before: Client -> Adapter -> Internal -> Adapter -> Handler
    After:  Client -> Handler (direct)

    No more:
    - handlerAdapter bridging interfaces
    - voidProcessorAdapter for void functionality
    - convertInternalToPublicContext conversions
    - Complex type mapping between layers

This refactoring provides a much cleaner, simpler architecture where all
push notification logic lives in the root package with direct access to
concrete Redis client types, eliminating unnecessary complexity while
maintaining full functionality and type safety.
2025-07-04 21:13:47 +03:00
Nedyalko Dyakov
d530d45b9b feat: implement strongly typed HandlerContext with concrete types in main package
Move push notification handler and context interfaces to main package to enable
strongly typed getters using concrete Redis client types instead of interfaces.
This provides much better type safety and usability for push notification handlers.

Key Changes:

1. Main Package Implementation:
   - Moved PushNotificationHandlerContext to push_notifications.go
   - Moved PushNotificationHandler to push_notifications.go
   - Implemented concrete types for all getters
   - GetClusterClient() returns *ClusterClient
   - GetSentinelClient() returns *SentinelClient
   - GetRegularClient() returns *Client
   - GetPubSub() returns *PubSub

2. Concrete Type Benefits:
   - No need for interface definitions or type assertions
   - Direct access to concrete client methods and properties
   - Compile-time type checking with actual client types
   - IntelliSense support for all client-specific methods
   - No runtime panics from incorrect type casting

3. Handler Interface with Concrete Types:
   ```go
   type PushNotificationHandlerContext interface {
       GetClusterClient() *ClusterClient
       GetSentinelClient() *SentinelClient
       GetRegularClient() *Client
       GetPubSub() *PubSub
       GetConn() *pool.Conn
       IsBlocking() bool
   }
   ```

4. Adapter Pattern Implementation:
   - Created handlerAdapter to bridge internal and public interfaces
   - Created voidProcessorAdapter for void processor functionality
   - Seamless conversion between internal and public contexts
   - Maintains compatibility with existing internal architecture

5. Context Conversion Functions:
   - convertInternalToPublicContext() for seamless conversion
   - Proper context bridging between internal and public APIs
   - Maintains all context information during conversion
   - Consistent behavior across all client types

6. Updated All Integration Points:
   - Updated redis.go to use public context conversion
   - Updated pubsub.go to use public context conversion
   - Updated sentinel.go to use void processor adapter
   - Maintained backward compatibility with existing code

7. Handler Usage Example:
   ```go
   func (h *MyHandler) HandlePushNotification(
       ctx context.Context,
       handlerCtx PushNotificationHandlerContext,
       notification []interface{},
   ) bool {
       // Direct access to concrete types - no casting needed!
       if clusterClient := handlerCtx.GetClusterClient(); clusterClient != nil {
           // Full access to ClusterClient methods
           nodes := clusterClient.ClusterNodes(ctx)
           // ... cluster-specific logic
       }

       if regularClient := handlerCtx.GetRegularClient(); regularClient != nil {
           // Full access to Client methods
           info := regularClient.Info(ctx)
           // ... regular client logic
       }

       return true
   }
   ```

8. Type Safety Improvements:
   - No interface{} fields in public API
   - Concrete return types for all getters
   - Compile-time verification of client type usage
   - Clear API with explicit client type access
   - Enhanced developer experience with full type information

Benefits:
- Strongly typed access to concrete Redis client types
- No type assertions or interface casting required
- Full IntelliSense support for client-specific methods
- Compile-time type checking prevents runtime errors
- Clean public API with concrete types
- Seamless integration with existing internal architecture
- Enhanced developer experience and productivity

This implementation provides handlers with direct access to concrete Redis
client types while maintaining the flexibility and context information needed
for sophisticated push notification handling, particularly important for
hitless upgrades and cluster management operations.
2025-07-04 20:04:03 +03:00
Nedyalko Dyakov
1606de8b73 feat: implement strongly typed HandlerContext interface
Convert HandlerContext from struct to interface with strongly typed getters
for different client types. This provides better type safety and a cleaner
API for push notification handlers while maintaining flexibility.

Key Changes:

1. HandlerContext Interface Design:
   - Converted HandlerContext from struct to interface
   - Added strongly typed getters for different client types
   - GetClusterClient() returns ClusterClientInterface
   - GetSentinelClient() returns SentinelClientInterface
   - GetFailoverClient() returns FailoverClientInterface
   - GetRegularClient() returns RegularClientInterface
   - GetPubSub() returns PubSubInterface

2. Client Type Interfaces:
   - Defined ClusterClientInterface for cluster client access
   - Defined SentinelClientInterface for sentinel client access
   - Defined FailoverClientInterface for failover client access
   - Defined RegularClientInterface for regular client access
   - Defined PubSubInterface for pub/sub access
   - Each interface provides String() method for basic operations

3. Concrete Implementation:
   - Created handlerContext struct implementing HandlerContext interface
   - Added NewHandlerContext constructor function
   - Implemented type-safe getters with interface casting
   - Returns nil for incorrect client types (type safety)

4. Updated All Usage:
   - Updated Handler interface to use HandlerContext interface
   - Updated ProcessorInterface to use HandlerContext interface
   - Updated all processor implementations (Processor, VoidProcessor)
   - Updated all handler context creation sites
   - Updated test handlers and test context creation

5. Helper Methods:
   - Updated pushNotificationHandlerContext() in baseClient
   - Updated pushNotificationHandlerContext() in PubSub
   - Consistent context creation across all client types
   - Proper parameter passing for different connection types

6. Type Safety Benefits:
   - Handlers can safely cast to specific client types
   - Compile-time checking for client type access
   - Clear API for accessing different client capabilities
   - No runtime panics from incorrect type assertions

7. API Usage Example:
   ```go
   func (h *MyHandler) HandlePushNotification(
       ctx context.Context,
       handlerCtx HandlerContext,
       notification []interface{},
   ) bool {
       // Strongly typed access
       if clusterClient := handlerCtx.GetClusterClient(); clusterClient != nil {
           // Handle cluster-specific logic
       }
       if sentinelClient := handlerCtx.GetSentinelClient(); sentinelClient != nil {
           // Handle sentinel-specific logic
       }
       return true
   }
   ```

8. Backward Compatibility:
   - Interface maintains same functionality as original struct
   - All existing handler patterns continue to work
   - No breaking changes to handler implementations
   - Smooth migration path for existing code

Benefits:
- Strong type safety for client access in handlers
- Clear API with explicit client type getters
- Compile-time checking prevents runtime errors
- Flexible interface allows future extensions
- Better separation of concerns between client types
- Enhanced developer experience with IntelliSense support

This enhancement provides handlers with strongly typed access to different
Redis client types while maintaining the flexibility and context information
needed for sophisticated push notification handling, particularly important
for hitless upgrades and cluster management operations.
2025-07-04 19:53:19 +03:00
Nedyalko Dyakov
47dd490a8a feat: enhance push notification handlers with context information 2025-07-04 18:16:15 +03:00
Nedyalko Dyakov
b6e712b41a feat: add proactive push notification processing to WithReader
- Add push notification processing to Conn.WithReader method
- Process notifications immediately before every read operation
- Provides proactive notification handling vs reactive processing
- Add proper error handling with internal.Logger
- Non-blocking implementation that doesn't break Redis operations
- Complements existing processing in Pool.Put and isHealthyConn

Benefits:
- Immediate processing when notifications arrive
- Called before every read operation for optimal timing
- Prevents notification backlog accumulation
- More responsive to Redis cluster changes
- Better user experience during migrations
- Optimal placement for catching asynchronous notifications

Implementation:
- Type-safe interface assertion for processor
- Context-aware error handling with logging
- Maintains backward compatibility
- Consistent with existing pool patterns
- Three-layer processing strategy: WithReader (proactive) + Pool.Put + isHealthyConn (reactive)

Use cases:
- MOVING/MIGRATING/MIGRATED notifications for slot migrations
- FAILING_OVER/FAILED_OVER notifications for failover scenarios
- Real-time cluster topology change awareness
- Improved connection utilization efficiency
2025-06-27 22:56:04 +03:00
Nedyalko Dyakov
f7948b5c5c fix: address pr review 2025-06-27 18:26:15 +03:00
Nedyalko Dyakov
e6c5590255 feat: enable real push notification processors for SentinelClient and FailoverClient
- Add PushNotifications field to FailoverOptions struct
- Update clientOptions() to pass PushNotifications field to Options
- Change SentinelClient and FailoverClient initialization to use same logic as regular Client
- Both clients now support real push notification processors when enabled
- Both clients use void processors only when explicitly disabled
- Consistent behavior across all client types (Client, SentinelClient, FailoverClient)

Benefits:
- SentinelClient and FailoverClient can now fully utilize push notifications
- Consistent API across all client types
- Real processors when push notifications are enabled
- Void processors only when explicitly disabled
- Equal push notification capabilities for all Redis client types
2025-06-27 14:03:50 +03:00
Nedyalko Dyakov
d3f61973c1 feat: add GetHandler method and improve push notification API encapsulation
- Add GetHandler() method to PushNotificationProcessorInterface for better encapsulation
- Add GetPushNotificationHandler() convenience method to Client and SentinelClient
- Remove HasHandlers() check from ProcessPendingNotifications to ensure notifications are always consumed
- Use PushNotificationProcessorInterface in internal pool package for proper abstraction
- Maintain GetRegistry() for backward compatibility and testing
- Update pubsub to use GetHandler() instead of GetRegistry() for cleaner code

Benefits:
- Better API encapsulation - no need to expose entire registry
- Cleaner interface - direct access to specific handlers
- Always consume push notifications from reader regardless of handler presence
- Proper abstraction in internal pool package
- Backward compatibility maintained
- Consistent behavior across all processor types
2025-06-27 13:59:43 +03:00
Nedyalko Dyakov
ad16b21487 fix: initialize push notification processor in NewFailoverClient
- Add push processor initialization to NewFailoverClient to prevent nil pointer dereference
- Use VoidPushNotificationProcessor for failover clients (typically don't need push notifications)
- Ensure consistent behavior across all client creation paths including failover scenarios
- Complete the coverage of all client types that inherit from baseClient

This fixes the final nil pointer dereference that was occurring in failover client
contexts where the pushProcessor field was nil, causing segmentation violations
during Redis operations in sentinel-managed failover scenarios.
2025-06-27 13:41:30 +03:00
Nedyalko Dyakov
d1d4529abf fix: initialize push notification processor in SentinelClient
- Add push processor initialization to NewSentinelClient to prevent nil pointer dereference
- Add GetPushNotificationProcessor and RegisterPushNotificationHandler methods to SentinelClient
- Use VoidPushNotificationProcessor for Sentinel (typically doesn't need push notifications)
- Ensure consistent behavior across all client types that inherit from baseClient

This fixes the panic that was occurring in Sentinel contexts where the pushProcessor
field was nil, causing segmentation violations when processing commands.
2025-06-27 01:47:21 +03:00
Damian Cherubini
0383d08a35 feat(client): Add CredentialsProvider field to UniversalOptions (#2927)
* Add CredentialsProvider field to universal client

* fix(options): Add credentials providers to universal options and pass to client options

* chore(ring): Add missing fields in building clientOptions

---------

Co-authored-by: ofekshenawa <104765379+ofekshenawa@users.noreply.github.com>
Co-authored-by: Nedyalko Dyakov <nedyalko.dyakov@gmail.com>
Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com>
2025-06-24 13:28:54 +03:00
Nedyalko Dyakov
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
fukua95
6c6dddcf7c feat: add ParseFailoverURL (#3362)
* add ParseFailoverURL for FailoverOptions
* fix 2 warning

Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com>
2025-05-15 14:53:40 +03:00
Nedyalko Dyakov
d54e848055 feat(options): panic when options are nil (#3363)
Client creation should panic when options are nil.
2025-04-30 09:33:40 +03:00
Nedyalko Dyakov
e191cf9dbe fix: better error handling when fetching the master node from the sentinels (#3349)
* Better error handling when fetching the master node from the sentinels

* fix error message generation

* close the errCh to not block

* use len over errCh
2025-04-17 16:31:07 +03:00
Naveen Prashanth
a4aea258fc Ensure context isn't exhausted via concurrent query as opposed to sentinel query (#3334) 2025-04-16 22:32:40 +03:00
Bulat Khasanov
eedb171825 Use DB option in NewFailoverClusterClient (#3342) 2025-04-15 16:57:50 +03:00
Nedyalko Dyakov
d236865b0c fix: handle network error on SETINFO (#3295) (CVE-2025-29923)
* fix: handle network error on SETINFO

This fix addresses potential out of order responses as described in `CVE-2025-29923`

* fix: deprecate DisableIndentity and introduce DisableIdentity

Both options will work before V10. In v10 DisableIndentity will be dropped. The preferred flag to use is `DisableIdentity`.
2025-03-19 19:02:36 +02:00
ofekshenawa
04005cbdc7 Support Resp 3 Redis Search Unstable Mode (#3098)
* Updated module version that points to retracted package version (#3074)

* Updated module version that points to retracted package version

* Updated testing image to latest

* support raw parsing for problematic Redis Search types

* Add UnstableResp3SearchModule to client options

* Add tests for Resp3 Search unstable mode

* Add tests for Resp3 Search unstable mode

* Add readme note

* Add words to spellcheck

* Add UnstableResp3SearchModule check to assertStableCommand

* Fix assertStableCommand logic

* remove go.mod changes

* Check panic occur on tests

* rename method

* update errors

* Rename flag to UnstableResp3

---------

Co-authored-by: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com>
Co-authored-by: vladvildanov <divinez122@outlook.com>
2024-09-12 11:26:10 +03:00
ofekshenawa
5da49b1aba bug: Fix SETINFO ensuring it is set-and-forget (#2915)
* Exexcute set-info without validation

* Fix tests

* Remove spaces from runtime.Version

* fix typo

* Send setinfo after auth

* Add pipline

* fix golangci

* revert fixing typo

* support sentinel
2024-02-20 17:34:35 +02:00
ofekshenawa
a32be3d93d Add Suffix support to default client set info (#2852)
* Add Suffix support to defualt client set info

* Change ClientNameSuffix to IdentitySuffix

* add tests
2024-01-04 14:40:14 +02:00
Tiago Peczenyj
a5fe17472a Option types must propagage missing fields (#2726)
* must propagage missing fields

Signed-off-by: Tiago Peczenyj <tpeczenyj@weborama.com>

* remove credentials provider from ring

---------

Signed-off-by: Tiago Peczenyj <tpeczenyj@weborama.com>
Co-authored-by: ofekshenawa <104765379+ofekshenawa@users.noreply.github.com>
2023-10-30 14:36:44 +02:00
chenjie199234
fd13da4fea fix missing fields in different Options (#2757)
* fix missing fields in different Options

* fix missing fields in different Options

---------

Co-authored-by: chenjie199234 <chenjie199234@gmail.com>
Co-authored-by: ofekshenawa <104765379+ofekshenawa@users.noreply.github.com>
2023-10-30 14:35:51 +02:00
ljun20160606
391798880c feat: add protocol option (#2598) 2023-05-16 22:02:22 +08:00
Vladimir Mihailenco
97b491aace chore: update import path 2023-01-23 08:48:54 +02:00
Vladimir Mihailenco
767109c632 chore: cleanup names 2023-01-21 10:30:02 +02:00
monkey
97697f488f feat: hook mode is changed to FIFO
Signed-off-by: monkey <golang@88.com>
2023-01-20 23:19:49 +08:00
monkey92t
a872c35b1a feat: add ClientName option
Signed-off-by: monkey92t <golang@88.com>
2022-12-28 22:14:52 +08:00
Vladimir Mihailenco
2ec03d9b37 fix: late binding for dial hook 2022-10-12 15:00:06 +03:00
Vladimir Mihailenco
0dff3d1461 feat: add OpenTelemetry metrics instrumentation 2022-10-12 11:09:41 +03:00
Vladimir Mihailenco
58f7149e38 feat: add ContextTimeoutEnabled to respect context timeouts and deadlines 2022-10-11 10:22:42 +03:00
Mikhail Mazurskiy
63392a363a fix: return early when context signals done 2022-08-26 20:55:45 +10:00
Vladimir Mihailenco
f6a8adc50c fix: remove conn reaper from the pool and uptrace option names 2022-07-28 15:17:59 +03:00
Knut Zuidema
e061db8c13 refactor: remove unused context attributes (#2154)
* refactor: remove unused context field
2022-07-14 13:43:42 +03:00
Vladimir Mihailenco
4ddd7d1803 chore: remove WithContext 2022-06-05 09:58:05 +03:00
Vladimir Mihailenco
a18fad5bd3 chore: v9 2022-06-04 17:42:06 +03:00
Vladimir Mihailenco
d09c27e604 feat: upgrade to Redis 7 2022-06-04 17:25:12 +03:00