mirror of
				https://github.com/redis/go-redis.git
				synced 2025-11-04 02:33:24 +03:00 
			
		
		
		
	chore(ci): Add redis 8.4-RC1-pre & examples (#3572)
* add disable maintnotifications example * add 8.4-RC1-pre * println -> printf for linter * address jit comment
This commit is contained in:
		
							
								
								
									
										6
									
								
								.github/actions/run-tests/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/actions/run-tests/action.yml
									
									
									
									
										vendored
									
									
								
							@@ -18,22 +18,20 @@ runs:
 | 
				
			|||||||
    - name: Setup Test environment
 | 
					    - name: Setup Test environment
 | 
				
			||||||
      env:
 | 
					      env:
 | 
				
			||||||
        REDIS_VERSION: ${{ inputs.redis-version }}
 | 
					        REDIS_VERSION: ${{ inputs.redis-version }}
 | 
				
			||||||
        CLIENT_LIBS_TEST_IMAGE: "redislabs/client-libs-test:${{ inputs.redis-version }}"
 | 
					 | 
				
			||||||
      run: |
 | 
					      run: |
 | 
				
			||||||
        set -e
 | 
					        set -e
 | 
				
			||||||
        redis_version_np=$(echo "$REDIS_VERSION" | grep -oP '^\d+.\d+')
 | 
					        redis_version_np=$(echo "$REDIS_VERSION" | grep -oP '^\d+.\d+')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Mapping of redis version to redis testing containers
 | 
					        # Mapping of redis version to redis testing containers
 | 
				
			||||||
        declare -A redis_version_mapping=(
 | 
					        declare -A redis_version_mapping=(
 | 
				
			||||||
 | 
					          ["8.4.x"]="8.4-RC1-pre"
 | 
				
			||||||
          ["8.2.x"]="8.2.1-pre"
 | 
					          ["8.2.x"]="8.2.1-pre"
 | 
				
			||||||
          ["8.0.x"]="8.0.2"
 | 
					          ["8.0.x"]="8.0.2"
 | 
				
			||||||
          ["7.4.x"]="rs-7.4.0-v5"
 | 
					 | 
				
			||||||
          ["7.2.x"]="rs-7.2.0-v17"
 | 
					 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if [[ -v redis_version_mapping[$REDIS_VERSION] ]]; then
 | 
					        if [[ -v redis_version_mapping[$REDIS_VERSION] ]]; then
 | 
				
			||||||
          echo "REDIS_VERSION=${redis_version_np}" >> $GITHUB_ENV
 | 
					          echo "REDIS_VERSION=${redis_version_np}" >> $GITHUB_ENV
 | 
				
			||||||
          echo "REDIS_IMAGE=redis:${{ inputs.redis-version }}" >> $GITHUB_ENV
 | 
					          echo "REDIS_IMAGE=redis:${REDIS_VERSION}" >> $GITHUB_ENV
 | 
				
			||||||
          echo "CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test:${redis_version_mapping[$REDIS_VERSION]}" >> $GITHUB_ENV
 | 
					          echo "CLIENT_LIBS_TEST_IMAGE=redislabs/client-libs-test:${redis_version_mapping[$REDIS_VERSION]}" >> $GITHUB_ENV
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
          echo "Version not found in the mapping."
 | 
					          echo "Version not found in the mapping."
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							@@ -2,7 +2,7 @@ name: Go
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
on:
 | 
					on:
 | 
				
			||||||
  push:
 | 
					  push:
 | 
				
			||||||
    branches: [master, v9, v9.7, v9.8, 'ndyakov/*', 'ofekshenawa/*', 'htemelski-redis/*', 'ce/*']
 | 
					    branches: [master, v9, 'v9.*']
 | 
				
			||||||
  pull_request:
 | 
					  pull_request:
 | 
				
			||||||
    branches: [master, v9, v9.7, v9.8, 'ndyakov/*', 'ofekshenawa/*', 'htemelski-redis/*', 'ce/*']
 | 
					    branches: [master, v9, v9.7, v9.8, 'ndyakov/*', 'ofekshenawa/*', 'htemelski-redis/*', 'ce/*']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -18,9 +18,9 @@ jobs:
 | 
				
			|||||||
      fail-fast: false
 | 
					      fail-fast: false
 | 
				
			||||||
      matrix:
 | 
					      matrix:
 | 
				
			||||||
        redis-version:
 | 
					        redis-version:
 | 
				
			||||||
 | 
					          - "8.4.x" # Redis CE 8.4
 | 
				
			||||||
          - "8.2.x" # Redis CE 8.2
 | 
					          - "8.2.x" # Redis CE 8.2
 | 
				
			||||||
          - "8.0.x" # Redis CE 8.0
 | 
					          - "8.0.x" # Redis CE 8.0
 | 
				
			||||||
          - "7.4.x" # Redis stack 7.4
 | 
					 | 
				
			||||||
        go-version:
 | 
					        go-version:
 | 
				
			||||||
          - "1.23.x"
 | 
					          - "1.23.x"
 | 
				
			||||||
          - "1.24.x"
 | 
					          - "1.24.x"
 | 
				
			||||||
@@ -44,9 +44,9 @@ jobs:
 | 
				
			|||||||
          
 | 
					          
 | 
				
			||||||
          # Mapping of redis version to redis testing containers
 | 
					          # Mapping of redis version to redis testing containers
 | 
				
			||||||
          declare -A redis_version_mapping=(
 | 
					          declare -A redis_version_mapping=(
 | 
				
			||||||
 | 
					            ["8.4.x"]="8.4-RC1-pre"
 | 
				
			||||||
            ["8.2.x"]="8.2.1-pre"
 | 
					            ["8.2.x"]="8.2.1-pre"
 | 
				
			||||||
            ["8.0.x"]="8.0.2"
 | 
					            ["8.0.x"]="8.0.2"
 | 
				
			||||||
            ["7.4.x"]="rs-7.4.0-v5"
 | 
					 | 
				
			||||||
          )
 | 
					          )
 | 
				
			||||||
          if [[ -v redis_version_mapping[$REDIS_VERSION] ]]; then
 | 
					          if [[ -v redis_version_mapping[$REDIS_VERSION] ]]; then
 | 
				
			||||||
            echo "REDIS_VERSION=${redis_version_np}" >> $GITHUB_ENV
 | 
					            echo "REDIS_VERSION=${redis_version_np}" >> $GITHUB_ENV
 | 
				
			||||||
@@ -74,10 +74,9 @@ jobs:
 | 
				
			|||||||
        fail-fast: false
 | 
					        fail-fast: false
 | 
				
			||||||
        matrix:
 | 
					        matrix:
 | 
				
			||||||
          redis-version:
 | 
					          redis-version:
 | 
				
			||||||
 | 
					            - "8.4.x" # Redis CE 8.4
 | 
				
			||||||
            - "8.2.x" # Redis CE 8.2
 | 
					            - "8.2.x" # Redis CE 8.2
 | 
				
			||||||
            - "8.0.x" # Redis CE 8.0
 | 
					            - "8.0.x" # Redis CE 8.0
 | 
				
			||||||
            - "7.4.x" # Redis stack 7.4
 | 
					 | 
				
			||||||
            - "7.2.x" # Redis stack 7.2
 | 
					 | 
				
			||||||
          go-version:
 | 
					          go-version:
 | 
				
			||||||
            - "1.23.x"
 | 
					            - "1.23.x"
 | 
				
			||||||
            - "1.24.x"
 | 
					            - "1.24.x"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,8 +1,8 @@
 | 
				
			|||||||
GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | sort)
 | 
					GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | sort)
 | 
				
			||||||
REDIS_VERSION ?= 8.2
 | 
					REDIS_VERSION ?= 8.4
 | 
				
			||||||
RE_CLUSTER ?= false
 | 
					RE_CLUSTER ?= false
 | 
				
			||||||
RCE_DOCKER ?= true
 | 
					RCE_DOCKER ?= true
 | 
				
			||||||
CLIENT_LIBS_TEST_IMAGE ?= redislabs/client-libs-test:8.2.1-pre
 | 
					CLIENT_LIBS_TEST_IMAGE ?= redislabs/client-libs-test:8.4-RC1-pre
 | 
				
			||||||
 | 
					
 | 
				
			||||||
docker.start:
 | 
					docker.start:
 | 
				
			||||||
	export RE_CLUSTER=$(RE_CLUSTER) && \
 | 
						export RE_CLUSTER=$(RE_CLUSTER) && \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
services:
 | 
					services:
 | 
				
			||||||
  redis:
 | 
					  redis:
 | 
				
			||||||
    image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.2.1-pre}
 | 
					    image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.4-RC1-pre}
 | 
				
			||||||
    platform: linux/amd64
 | 
					    platform: linux/amd64
 | 
				
			||||||
    container_name: redis-standalone
 | 
					    container_name: redis-standalone
 | 
				
			||||||
    environment:
 | 
					    environment:
 | 
				
			||||||
@@ -23,7 +23,7 @@ services:
 | 
				
			|||||||
      - all
 | 
					      - all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  osscluster:
 | 
					  osscluster:
 | 
				
			||||||
    image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.2.1-pre}
 | 
					    image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.4-RC1-pre}
 | 
				
			||||||
    platform: linux/amd64
 | 
					    platform: linux/amd64
 | 
				
			||||||
    container_name: redis-osscluster
 | 
					    container_name: redis-osscluster
 | 
				
			||||||
    environment:
 | 
					    environment:
 | 
				
			||||||
@@ -40,7 +40,7 @@ services:
 | 
				
			|||||||
      - all
 | 
					      - all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sentinel-cluster:
 | 
					  sentinel-cluster:
 | 
				
			||||||
    image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.2.1-pre}
 | 
					    image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.4-RC1-pre}
 | 
				
			||||||
    platform: linux/amd64
 | 
					    platform: linux/amd64
 | 
				
			||||||
    container_name: redis-sentinel-cluster
 | 
					    container_name: redis-sentinel-cluster
 | 
				
			||||||
    network_mode: "host"
 | 
					    network_mode: "host"
 | 
				
			||||||
@@ -60,7 +60,7 @@ services:
 | 
				
			|||||||
      - all
 | 
					      - all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sentinel:
 | 
					  sentinel:
 | 
				
			||||||
    image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.2.1-pre}
 | 
					    image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.4-RC1-pre}
 | 
				
			||||||
    platform: linux/amd64
 | 
					    platform: linux/amd64
 | 
				
			||||||
    container_name: redis-sentinel
 | 
					    container_name: redis-sentinel
 | 
				
			||||||
    depends_on:
 | 
					    depends_on:
 | 
				
			||||||
@@ -84,7 +84,7 @@ services:
 | 
				
			|||||||
      - all
 | 
					      - all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ring-cluster:
 | 
					  ring-cluster:
 | 
				
			||||||
    image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.2.1-pre}
 | 
					    image: ${CLIENT_LIBS_TEST_IMAGE:-redislabs/client-libs-test:8.4-RC1-pre}
 | 
				
			||||||
    platform: linux/amd64
 | 
					    platform: linux/amd64
 | 
				
			||||||
    container_name: redis-ring-cluster
 | 
					    container_name: redis-ring-cluster
 | 
				
			||||||
    environment:
 | 
					    environment:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										133
									
								
								example/disable-maintnotifications/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								example/disable-maintnotifications/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
				
			|||||||
 | 
					# Disable Maintenance Notifications Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This example demonstrates how to use the go-redis client with maintenance notifications **disabled**.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## What are Maintenance Notifications?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Maintenance notifications are a Redis Cloud feature that allows the server to notify clients about:
 | 
				
			||||||
 | 
					- Planned maintenance events
 | 
				
			||||||
 | 
					- Failover operations
 | 
				
			||||||
 | 
					- Node migrations
 | 
				
			||||||
 | 
					- Cluster topology changes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The go-redis client supports three modes:
 | 
				
			||||||
 | 
					- **`ModeDisabled`**: Client doesn't send `CLIENT MAINT_NOTIFICATIONS ON` command
 | 
				
			||||||
 | 
					- **`ModeEnabled`**: Client forcefully sends the command, interrupts connection on error
 | 
				
			||||||
 | 
					- **`ModeAuto`** (default): Client tries to send the command, disables feature on error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## When to Disable Maintenance Notifications
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You should disable maintenance notifications when:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. **Connecting to non-Redis Cloud / Redis Enterprise instances** - Standard Redis servers don't support this feature
 | 
				
			||||||
 | 
					2. **You want to handle failovers manually** - Your application has custom failover logic
 | 
				
			||||||
 | 
					3. **Minimizing client-side overhead** - You want the simplest possible client behavior
 | 
				
			||||||
 | 
					4. **The Redis server doesn't support the feature** - Older Redis versions or forks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Usage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Basic Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
					    "github.com/redis/go-redis/v9"
 | 
				
			||||||
 | 
					    "github.com/redis/go-redis/v9/maintnotifications"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rdb := redis.NewClient(&redis.Options{
 | 
				
			||||||
 | 
					    Addr: "localhost:6379",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Explicitly disable maintenance notifications
 | 
				
			||||||
 | 
					    MaintNotificationsConfig: &maintnotifications.Config{
 | 
				
			||||||
 | 
					        Mode: maintnotifications.ModeDisabled,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					defer rdb.Close()
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Cluster Client Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					rdbCluster := redis.NewClusterClient(&redis.ClusterOptions{
 | 
				
			||||||
 | 
					    Addrs: []string{"localhost:7000", "localhost:7001", "localhost:7002"},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Disable maintenance notifications for cluster
 | 
				
			||||||
 | 
					    MaintNotificationsConfig: &maintnotifications.Config{
 | 
				
			||||||
 | 
					        Mode: maintnotifications.ModeDisabled,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					defer rdbCluster.Close()
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Default Behavior (ModeAuto)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you don't specify `MaintNotifications`, the client defaults to `ModeAuto`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					// This uses ModeAuto by default
 | 
				
			||||||
 | 
					rdb := redis.NewClient(&redis.Options{
 | 
				
			||||||
 | 
					    Addr: "localhost:6379",
 | 
				
			||||||
 | 
					    // MaintNotificationsConfig: nil means ModeAuto
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					With `ModeAuto`, the client will:
 | 
				
			||||||
 | 
					1. Try to enable maintenance notifications
 | 
				
			||||||
 | 
					2. If the server doesn't support it, silently disable the feature
 | 
				
			||||||
 | 
					3. Continue normal operation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Running the Example
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Start a Redis server:
 | 
				
			||||||
 | 
					   ```bash
 | 
				
			||||||
 | 
					   redis-server --port 6379
 | 
				
			||||||
 | 
					   ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Run the example:
 | 
				
			||||||
 | 
					   ```bash
 | 
				
			||||||
 | 
					   go run main.go
 | 
				
			||||||
 | 
					   ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Expected Output
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					=== Example 1: Explicitly Disabled ===
 | 
				
			||||||
 | 
					✓ Connected successfully (maintenance notifications disabled)
 | 
				
			||||||
 | 
					✓ SET operation successful
 | 
				
			||||||
 | 
					✓ GET operation successful: value1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Example 2: Default Behavior (ModeAuto) ===
 | 
				
			||||||
 | 
					✓ Connected successfully (maintenance notifications auto-enabled)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Example 3: Cluster Client with Disabled Notifications ===
 | 
				
			||||||
 | 
					Cluster not available (expected): ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Example 4: Performance Comparison ===
 | 
				
			||||||
 | 
					✓ 1000 SET operations (disabled): 45ms
 | 
				
			||||||
 | 
					✓ 1000 SET operations (auto): 46ms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Cleanup ===
 | 
				
			||||||
 | 
					✓ Database flushed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Summary ===
 | 
				
			||||||
 | 
					Maintenance notifications can be disabled by setting:
 | 
				
			||||||
 | 
					  MaintNotificationsConfig: &maintnotifications.Config{
 | 
				
			||||||
 | 
					    Mode: maintnotifications.ModeDisabled,
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is useful when:
 | 
				
			||||||
 | 
					  - Connecting to non-Redis Cloud instances
 | 
				
			||||||
 | 
					  - You want to handle failovers manually
 | 
				
			||||||
 | 
					  - You want to minimize client-side overhead
 | 
				
			||||||
 | 
					  - The Redis server doesn't support CLIENT MAINT_NOTIFICATIONS
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Performance Impact
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Disabling maintenance notifications has minimal performance impact. The main differences are:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. **Connection Setup**: One less command (`CLIENT MAINT_NOTIFICATIONS ON`) during connection initialization
 | 
				
			||||||
 | 
					2. **Runtime Overhead**: No background processing of maintenance notifications
 | 
				
			||||||
 | 
					3. **Memory Usage**: Slightly lower memory footprint (no notification handlers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In most cases, the performance difference is negligible (< 1%).
 | 
				
			||||||
							
								
								
									
										12
									
								
								example/disable-maintnotifications/go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								example/disable-maintnotifications/go.mod
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					module github.com/redis/go-redis/example/disable-maintnotifications
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go 1.23
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace github.com/redis/go-redis/v9 => ../..
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require github.com/redis/go-redis/v9 v9.7.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require (
 | 
				
			||||||
 | 
						github.com/cespare/xxhash/v2 v2.3.0 // indirect
 | 
				
			||||||
 | 
						github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										8
									
								
								example/disable-maintnotifications/go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								example/disable-maintnotifications/go.sum
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
 | 
				
			||||||
 | 
					github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
 | 
				
			||||||
 | 
					github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
 | 
				
			||||||
 | 
					github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
 | 
				
			||||||
 | 
					github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 | 
				
			||||||
 | 
					github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 | 
				
			||||||
 | 
					github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 | 
				
			||||||
 | 
					github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 | 
				
			||||||
							
								
								
									
										144
									
								
								example/disable-maintnotifications/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								example/disable-maintnotifications/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,144 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/redis/go-redis/v9"
 | 
				
			||||||
 | 
						"github.com/redis/go-redis/v9/maintnotifications"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
						ctx := context.Background()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Example 0: Explicitly disable maintenance notifications
 | 
				
			||||||
 | 
						fmt.Println("=== Example 0: Explicitly Enabled ===")
 | 
				
			||||||
 | 
						rdb0 := redis.NewClient(&redis.Options{
 | 
				
			||||||
 | 
							Addr: "localhost:6379",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Explicitly disable maintenance notifications
 | 
				
			||||||
 | 
							// This prevents the client from sending CLIENT MAINT_NOTIFICATIONS ON
 | 
				
			||||||
 | 
							MaintNotificationsConfig: &maintnotifications.Config{
 | 
				
			||||||
 | 
								Mode: maintnotifications.ModeEnabled,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						defer rdb0.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Test the connection
 | 
				
			||||||
 | 
						if err := rdb0.Ping(ctx).Err(); err != nil {
 | 
				
			||||||
 | 
							fmt.Printf("Failed to connect: %v\n\n", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Println("When ModeEnabled, the client will return an error if the server doesn't support maintenance notifications.")
 | 
				
			||||||
 | 
						fmt.Printf("ModeAuto will silently disable the feature.\n\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Example 1: Explicitly disable maintenance notifications
 | 
				
			||||||
 | 
						fmt.Println("=== Example 1: Explicitly Disabled ===")
 | 
				
			||||||
 | 
						rdb1 := redis.NewClient(&redis.Options{
 | 
				
			||||||
 | 
							Addr: "localhost:6379",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Explicitly disable maintenance notifications
 | 
				
			||||||
 | 
							// This prevents the client from sending CLIENT MAINT_NOTIFICATIONS ON
 | 
				
			||||||
 | 
							MaintNotificationsConfig: &maintnotifications.Config{
 | 
				
			||||||
 | 
								Mode: maintnotifications.ModeDisabled,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						defer rdb1.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Test the connection
 | 
				
			||||||
 | 
						if err := rdb1.Ping(ctx).Err(); err != nil {
 | 
				
			||||||
 | 
							fmt.Printf("Failed to connect: %v\n\n", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Println("✓ Connected successfully (maintenance notifications disabled)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Perform some operations
 | 
				
			||||||
 | 
						if err := rdb1.Set(ctx, "example:key1", "value1", 0).Err(); err != nil {
 | 
				
			||||||
 | 
							fmt.Printf("Failed to set key: %v\n\n", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Println("✓ SET operation successful")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val, err := rdb1.Get(ctx, "example:key1").Result()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Printf("Failed to get key: %v\n\n", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Printf("✓ GET operation successful: %s\n\n", val)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Example 2: Using nil config (defaults to ModeAuto)
 | 
				
			||||||
 | 
						fmt.Printf("\n=== Example 2: Default Behavior (ModeAuto) ===\n")
 | 
				
			||||||
 | 
						rdb2 := redis.NewClient(&redis.Options{
 | 
				
			||||||
 | 
							Addr: "localhost:6379",
 | 
				
			||||||
 | 
							// MaintNotifications: nil means ModeAuto (enabled for Redis Cloud)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						defer rdb2.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := rdb2.Ping(ctx).Err(); err != nil {
 | 
				
			||||||
 | 
							fmt.Printf("Failed to connect: %v\n\n", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Println("✓ Connected successfully (maintenance notifications auto-enabled)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Example 4: Comparing behavior with and without maintenance notifications
 | 
				
			||||||
 | 
						fmt.Printf("\n=== Example 4: Performance Comparison ===\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Client with auto-enabled notifications
 | 
				
			||||||
 | 
						startauto := time.Now()
 | 
				
			||||||
 | 
						for i := 0; i < 1000; i++ {
 | 
				
			||||||
 | 
							key := fmt.Sprintf("test:auto:%d", i)
 | 
				
			||||||
 | 
							if err := rdb2.Set(ctx, key, i, time.Minute).Err(); err != nil {
 | 
				
			||||||
 | 
								fmt.Printf("Failed to set key: %v\n", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						autoDuration := time.Since(startauto)
 | 
				
			||||||
 | 
						fmt.Printf("✓ 1000 SET operations (auto): %v\n", autoDuration)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// print pool stats
 | 
				
			||||||
 | 
						fmt.Printf("Pool stats (auto): %+v\n", rdb2.PoolStats())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// give the server a moment to take chill
 | 
				
			||||||
 | 
						fmt.Println("---")
 | 
				
			||||||
 | 
						time.Sleep(time.Second)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Client with disabled notifications
 | 
				
			||||||
 | 
						start := time.Now()
 | 
				
			||||||
 | 
						for i := 0; i < 1000; i++ {
 | 
				
			||||||
 | 
							key := fmt.Sprintf("test:disabled:%d", i)
 | 
				
			||||||
 | 
							if err := rdb1.Set(ctx, key, i, time.Minute).Err(); err != nil {
 | 
				
			||||||
 | 
								fmt.Printf("Failed to set key: %v\n", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						disabledDuration := time.Since(start)
 | 
				
			||||||
 | 
						fmt.Printf("✓ 1000 SET operations (disabled): %v\n", disabledDuration)
 | 
				
			||||||
 | 
						fmt.Printf("Pool stats (disabled): %+v\n", rdb1.PoolStats())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// performance comparison note
 | 
				
			||||||
 | 
						fmt.Printf("\nNote: The pool stats and performance are identical because there is no background processing overhead.\n")
 | 
				
			||||||
 | 
						fmt.Println("Since the server doesn't support maintenance notifications, there is no difference in behavior.")
 | 
				
			||||||
 | 
						fmt.Printf("The only difference is that the \"ModeDisabled\" client doesn't send the CLIENT MAINT_NOTIFICATIONS ON command.\n\n")
 | 
				
			||||||
 | 
						fmt.Println("p.s. reordering the execution here makes it look like there is a small performance difference, but it's just noise.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Cleanup
 | 
				
			||||||
 | 
						fmt.Printf("\n=== Cleanup ===\n")
 | 
				
			||||||
 | 
						if err := rdb1.FlushDB(ctx).Err(); err != nil {
 | 
				
			||||||
 | 
							fmt.Printf("Failed to flush DB: %v\n", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Println("✓ Database flushed")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fmt.Printf("\n=== Summary ===\n")
 | 
				
			||||||
 | 
						fmt.Println("Maintenance notifications can be disabled by setting:")
 | 
				
			||||||
 | 
						fmt.Println("  MaintNotifications: &maintnotifications.Config{")
 | 
				
			||||||
 | 
						fmt.Println("    Mode: maintnotifications.ModeDisabled,")
 | 
				
			||||||
 | 
						fmt.Println("  }")
 | 
				
			||||||
 | 
						fmt.Printf("\nThis is useful when:\n")
 | 
				
			||||||
 | 
						fmt.Println("  - Connecting to non-Redis Cloud instances")
 | 
				
			||||||
 | 
						fmt.Println("  - You want to handle failovers manually")
 | 
				
			||||||
 | 
						fmt.Println("  - You want to minimize client-side overhead")
 | 
				
			||||||
 | 
						fmt.Println("  - The Redis server doesn't support CLIENT MAINT_NOTIFICATIONS")
 | 
				
			||||||
 | 
						fmt.Printf("\nFor more information, see:\n")
 | 
				
			||||||
 | 
						fmt.Println("  https://github.com/redis/go-redis/tree/master/maintnotifications")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -69,7 +69,7 @@ var RCEDocker = false
 | 
				
			|||||||
// Notes version of redis we are executing tests against.
 | 
					// Notes version of redis we are executing tests against.
 | 
				
			||||||
// This can be used before we change the bsm fork of ginkgo for one,
 | 
					// This can be used before we change the bsm fork of ginkgo for one,
 | 
				
			||||||
// which have support for label sets, so we can filter tests per redis version.
 | 
					// which have support for label sets, so we can filter tests per redis version.
 | 
				
			||||||
var RedisVersion float64 = 8.2
 | 
					var RedisVersion float64 = 8.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SkipBeforeRedisVersion(version float64, msg string) {
 | 
					func SkipBeforeRedisVersion(version float64, msg string) {
 | 
				
			||||||
	if RedisVersion < version {
 | 
						if RedisVersion < version {
 | 
				
			||||||
@@ -96,7 +96,7 @@ var _ = BeforeSuite(func() {
 | 
				
			|||||||
	RedisVersion, _ = strconv.ParseFloat(strings.Trim(os.Getenv("REDIS_VERSION"), "\""), 64)
 | 
						RedisVersion, _ = strconv.ParseFloat(strings.Trim(os.Getenv("REDIS_VERSION"), "\""), 64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if RedisVersion == 0 {
 | 
						if RedisVersion == 0 {
 | 
				
			||||||
		RedisVersion = 8.2
 | 
							RedisVersion = 8.4
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Printf("RECluster: %v\n", RECluster)
 | 
						fmt.Printf("RECluster: %v\n", RECluster)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user