Some questions about Redigo and concurrency
<p>I have read through the whole Redigo documentation which can be found here.
<a href="https://godoc.org/github.com/garyburd/redigo/redis#pkg-variables" rel="nofollow">https://godoc.org/github.com/garyburd/redigo/redis#pkg-variables</a></p>

<p>Here the documentation clearly states that connections do not support concurrent calls to Send(), Flush() or Receive() methods.</p>

<blockquote>
  <p>Connections do not support concurrent calls to the write methods
  (Send, Flush) or concurrent calls to the read method (Receive).
  Connections do allow a concurrent reader and writer.</p>
</blockquote>

<p>And then it states that since the Do method can be a combination of Send(), Flush() and Receive(), we can't use Do() concurrently (with) the other methods.</p>

<blockquote>
  <p>Because the Do method combines the functionality of Send, Flush and
  Receive, the  Do method cannot be called concurrently with the other
  methods.</p>
</blockquote>

<p>Does this mean that we can use Do() concurrently alone using a single connection stored in a global variable as long as we don't mix it with the other methods?</p>

<p>For example like this:</p>

<pre><code>var (

    // Redis Conn.
    redisConn redis.Conn

    // Redis PubSubConn wraps a Conn with convenience methods for subscribers.
    redisPsc redis.PubSubConn
)

func redisInit() {

    c, err := redis.Dial(config.RedisProtocol, config.RedisAddress)
    if err != nil {
        log.Fatal(err)
    }
    c.Do("AUTH", config.RedisPass)
    redisConn = c

    c, err = redis.Dial(config.RedisProtocol, config.RedisAddress)
    if err != nil {
        log.Fatal(err)
    }
    c.Do("AUTH", config.RedisPass)
    redisPsc = redis.PubSubConn{c}

    for {
        switch v := redisPsc.Receive().(type) {
        case redis.Message:
            // fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
            socketHub.broadcast &lt;- v.Data
        case redis.Subscription:
            // fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
        case error:
            log.Println(v)
        }
    }

}
</code></pre>

<p>And then calling the Do() method inside some go routine like this:</p>

<pre><code>if _, err = redisConn.Do("PUBLISH", fmt.Sprintf("user:%d", fromId), message); err != nil {
    log.Println(err)
}
if _, err = redisConn.Do("PUBLISH", fmt.Sprintf("user:%d", toId), message); err != nil {
    log.Println(err)
}
</code></pre>

<p>And then later the document says that for full concurrent access to Redis, we need to create a pool and get connections from the pool and release them when we are done with it.</p>

<p>Does this mean that I can use, Send(), Flush() and Receive() as I want, as long as I get a connection from the pool? So in other words every time I need to do something in a go routine I have to get a new connection from the pool instead of reusing a global connection? And does this mean that I can use the Do() method with for example Send() as long as I get a new connection from the pool?</p>

<p>So to sum up:</p>

<p>1) Can I use the Do() method concurrently as long as I do not use it with the Send, Flush and Receive methods?</p>

<p>2) Can I use everything as I want as long as I get a new connection from the pool and release it when I'm done?</p>

<p>3) If (1) is true, does this affect performance? Is it better to use a global connection concurrently with only using the Do() method as in the provided example by me, and not mixing things up with Send, Flush and Receive?</p>