redis / go-redis

Redis Go client
https://redis.uptrace.dev
BSD 2-Clause "Simplified" License
19.88k stars 2.34k forks source link

Pubsub stoped supporting "__redis__:invalidate" messages #3093

Open mikhailantoshkin opened 3 weeks ago

mikhailantoshkin commented 3 weeks ago

go-redis v9 stopped supporting __redis__:invalidate messages in pubsub channels

Expected Behavior

Pubsub allows receiving invalidate messages from the subscription on __redis__:invalidate channel

Current Behavior

In v9 pubsub.Receive returns error redis: unsupported pubsub message: "invalidate"

Steps to Reproduce

The following code snippet works fine on v8 but breaks on v9

package main

import (
    "context"
    "fmt"
    "time"

    "github.com/redis/go-redis/v9"
    //"github.com/go-redis/redis/v8"
)

func main() {
    ctx := context.Background()
    redisOptions := &redis.Options{
        Addr: "localhost:6379",
        OnConnect: func(ctx context.Context, cn *redis.Conn) error {
            cid := cn.ClientID(ctx).Val()
            return cn.Process(ctx, redis.NewBoolCmd(ctx, "CLIENT", "TRACKING", "ON", "REDIRECT", fmt.Sprintf("%v", cid), "BCAST", "PREFIX", "foo"))
        },
    }

    rdb:= redis.NewClient(redisOptions)

    pubsub := rdb.Subscribe(ctx, "__redis__:invalidate")

    go func() {
        defer pubsub.Close()
        for {
            fmt.Println("Listening...")
            msg, err := pubsub.Receive(ctx)
            if err != nil {
                fmt.Println(err) // v9 returns error
            }
            fmt.Println(msg)
        }
    }()

    time.Sleep(30 * time.Second)

}

Running this code with v8 produces the following output when issuing set foo 1 with redis-cli

Listening...
subscribe: __redis__:invalidate
Listening...
Message<__redis__:invalidate: >
Listening...

Running it with v9 produces the following output when issuing set foo 1 with redis-cli

Listening...
subscribe: __redis__:invalidate
Listening...
redis: unsupported pubsub message: "invalidate"
<nil>
Listening...

Context (Environment)

go version go1.22.6 linux/amd64

I'm implementing client-side cache invalidation (https://redis.io/docs/latest/develop/use/client-side-caching/#broadcasting-mode)

mikhailantoshkin commented 3 weeks ago

Also note: when subscribed to __redis__:invalidate on read-only replica, on full resynchronization the message both v9 and v8 breaks.

logs from redis-cli when full resynchronization is triggered

127.0.0.2:6379> client id
(integer) 1255
127.0.0.2:6379> CLIENT TRACKING on REDIRECT 1255 BCAST PREFIX foo
OK
127.0.0.2:6379> SUBSCRIBE  __redis__:invalidate
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "__redis__:invalidate"
3) (integer) 1
1) "message"
2) "__redis__:invalidate"
3) (nil)

Logs from the code example provided above for v9:

Listening...
subscribe: __redis__:invalidate
Listening...
redis: unsupported pubsub message: "invalidate"
<nil>
Listening...

Logs for v8

Listening...
subscribe: __redis__:invalidate
Listening...
redis: unsupported pubsub message payload: <nil>
<nil>
Listening...
goDeni commented 2 weeks ago

+1 same problem