opened
lght
username_0
Hi guys,

so far I've been doing this:

```
import (
	_redis "gopkg.in/redis.v3"
	"strconv"
	"time"
)

type Redis struct {
	Connector	*_redis.Client
	PubSub 		*_redis.PubSub
}

var redis *Redis = nil

func NewRedis() bool {
	if redis == nil {
		redis = new(Redis)
		redis.Connector = _redis.NewClient(&_redis.Options{
			Addr: config.RedisHostname + ":" + strconv.FormatInt(config.RedisPort, 10),
			Password: "",
			DB: 0,
		})
		Logger.Log(nil, "Connected to Redis")
		err := redis.Init()
		if err != nil {
			Logger.Fatal(nil, "Cannot setup Redis:", err.Error())
			return false
		}
		return true
	}
	return false
}

func (this *Redis) Init() error {
	pubsub, err := this.Connector.Subscribe("test")
	if err != nil {
		return err
	}
	defer pubsub.Close()
	this.PubSub = pubsub
	for {
		msgi, err := this.PubSub.ReceiveTimeout(100 * time.Millisecond)
		if err != nil {
			Logger.Error(nil, "PubSub error:", err.Error())
			err = this.PubSub.Ping("")
			if err != nil {
				Logger.Error(nil, "PubSub failure:", err.Error())
				break
			}
			continue
		}
		switch msg := msgi.(type) {
			case *_redis.Message:
				Logger.Log(nil, "Received", msg.Payload, "on channel", msg.Channel)
		}
	}
	return nil
}
```

My Connector is a redis.Client, it's working because I was able to publish messages as well.

When I run my program, I get the following error:
`PubSub error: WSARecv tcp 127.0.0.1:64505: i/o timeout`

Do you have any idea of what I'm doing wrong ?
Can't manage to have a working pub/sub
issue
created
vmihailenco
username_1
You did not show the full code so it is hard to say what exactly you are doing wrong. I suppose that you have something like that:

```
NewRedis() // this method blocks forever reading messages from the channel
redis.Connector.Publish("test", "hello") // Publish is never called
```

You you need to refactor `NewRedis`, e.g. extract pubsub reading loop and add proper synchronization. I suggest you to start with following code and adapt it as you need:

```
package main

import (
	"fmt"
	"time"

	goredis "gopkg.in/redis.v3"
)

func consumeMessages(pubsub *goredis.PubSub) {
	defer pubsub.Close()

	for {
		msgi, err := pubsub.ReceiveTimeout(time.Second)
		if err != nil {
			err := pubsub.Ping("")
			if err != nil {
				panic(err)
			}
			continue
		}

		switch msg := msgi.(type) {
		case *goredis.Subscription:
			// Ignore.
		case *goredis.Message:
			fmt.Println("received", msg.Payload, "on", msg.Channel)
		case *goredis.Pong:
			// Ignore.
		default:
			panic(fmt.Sprintf("unknown message: %#v", msgi))
		}
	}
}

func main() {
	redis := goredis.NewClient(&goredis.Options{
		Addr: ":6379",
	})

	pubsub, err := redis.Subscribe("mychannel")
	if err != nil {
		panic(err)
	}
	go consumeMessages(pubsub)

	for _ = range time.Tick(time.Second) {
		err := redis.Publish("mychannel", "hello").Err()
		if err != nil {
			panic(err)
		}
	}
}
```
comment
closed
lght
username_0
issue
created
lght
username_0
Answer is there (http://stackoverflow.com/questions/32315648/golang-redis-pubsub-timeout/32319061#32319061), and that's obvious, you don't really need to have a timeout in a routine (at least, in my case, I don't)
comment