miniredis icon indicating copy to clipboard operation
miniredis copied to clipboard

Using embedded subscribe and external client leads to io timeout

Open Olex1313 opened this issue 2 years ago • 5 comments

Hello, I've been using miniredis in my unit-tests and found unexpected behaviour when trying to subscribe with miniredis client and publish with https://github.com/redis/go-redis, which led to io timeout on publisher. Then I've switched to go-redis on both sides which worked fine. Am I doing something wrong or is it a bug?

I've attach a minimal reproducing example later

Olex1313 avatar Oct 06 '23 15:10 Olex1313

Hello, I've been using miniredis in my unit-tests and found unexpected behaviour when trying to subscribe with miniredis client and publish with https://github.com/redis/go-redis, which led to io timeout on publisher. Then I've switched to go-redis on both sides which worked fine. Am I doing something wrong or is it a bug?

Sounds like a bug :)

I've attach a minimal reproducing example later

That would be great, thanks!

alicebob avatar Oct 06 '23 16:10 alicebob

Also, make sure you use the /v2 version of miniredis.

alicebob avatar Oct 09 '23 07:10 alicebob

I've tried something like this:

func main() {
	mRedis, _ := miniredis.Run()
	mRedis.RequireUserAuth("hello", "world")
	redisUrl, _ := redis.ParseURL(fmt.Sprintf("redis://hello:world@%s", mRedis.Addr()))
	redisClient := redis.NewClient(redisUrl)

	miniSub := mRedis.NewSubscriber()
	miniSub.Subscribe("channel")

	curTime := time.Now()
	redisClient.Publish(context.Background(), "channel", "msg")
	println(time.Since(curTime) / 1000000000)

	curTime = time.Now()
	msgChan := miniSub.Messages()
	println(time.Since(curTime))

	select {
	case msg := <-msgChan:
		println(msg.Message)
	case <-time.After(time.Millisecond * 200):
		println("Too long")
	}
}

Apparently the problem is not exactly with publish, but somehow redis-go publishes a message approx 12 seconds :)

Miniredis version: github.com/alicebob/miniredis/v2 v2.30.5 redis-go version: github.com/redis/go-redis/v9 v9.1.0

Olex1313 avatar Oct 09 '23 07:10 Olex1313

I'll try to benchmark with native-redis, dockerized-redis and miniredis today, when I have more free time, but it looks strange, maybe it is even redis client issue

Olex1313 avatar Oct 09 '23 07:10 Olex1313

The problem is that "Publish" writes to a channel where nothing is reading on. If you change that to work in a Go routine it works for me:

    ...
    curTime := time.Now()
    go func() {
        redisClient.Publish(context.Background(), "channel", "msg")
        println(time.Since(curTime) / 1000000000)
    }()
    ...

alicebob avatar Oct 11 '23 07:10 alicebob