学习-4

作者: NotFoundW | 来源:发表于2020-04-14 15:29 被阅读0次

BLPOP命令相关(BRPOP完全一样)

  1. List存在且长度大于0,返回key name和pop出来的元素
  2. List存在且为空时,如果直到timeout之后都还是为空,就返回nil
  3. List不存在时,将在timeout之后返回nil
  4. BLPOP用在一个不是List的数据上,将会返回error

Code

func Blpop(c redis.Conn) {
    // use BLPOP normally
    c.Do("RPUSH", "sun", "rise")
    results, err := redis.Strings(c.Do("BLPOP", "sun", 3))
    if err != nil {
        colorlog.Error(err.Error())
        return
    }
    fmt.Println("Popped element belongs to list:", results[0])
    fmt.Println("Popped element's value:", results[1])
    // If list is null, will return nil after timeout
    c.Do("RPOP", "sun")
    result, err := c.Do("BLPOP", "sun", 3)
    if err != nil {
        colorlog.Error(err.Error())
        return
    }
    if result == nil {
        fmt.Println("If list is null, will return nil after timeout.")
    }
    // If key doesn't exist, will return nil after timeout
    c.Do("DEL", "bug")
    result, err = c.Do("BLPOP", "bug", 3)
    if err != nil {
        colorlog.Error(err.Error())
        return
    }
    if result == nil {
        fmt.Println("If key doesn't exist, will return nil after timeout.")
    }
    //  If use BLPOP on a key that is not a list, will return error
    c.Do("SET", "kkk", 12)
    _, err = c.Do("BLPOP", "kkk", 3)
    if err != nil {
        fmt.Println("If use BLPOP on a key that is not a list, will return error:")
        colorlog.Error(err.Error())
    }
}

Output

➤ go run main.go
Popped element belongs to list: sun
Popped element's value: rise
If list is null, will return nil after timeout.
If key doesn't exist, will return nil after timeout.
If use BLPOP on a key that is not a list, will return error:
[ERR]2020/04/14 15:15:11 WRONGTYPE Operation against a key holding the wrong kind of value

  1. BLPOP是LPOP的block版本,尝试一下当List为空时,在BLPOP的timeout之前,向List添加一个元素。
    另外,BRPOPLPUSH的实验方法跟BLPOP几乎一样。

Code

func main() {
    c1, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Println("Connect to redis error", err)
        return
    }
    defer c1.Close()
    c2, err := redis.Dial("tcp", "127.0.0.1:6379")
    if err != nil {
        fmt.Println("Connect to redis error", err)
        return
    }
    defer c2.Close()
    c1.Do("RPOP", "sun")
    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
        defer wg.Done()
        fmt.Println("BLPOP start:", time.Now().Format("2006/1/2 15:04:05"))
        results, err := redis.Strings(c1.Do("BLPOP", "sun", 20))
        fmt.Println("BLPOP end:", time.Now().Format("2006/1/2 15:04:05"))
        if err != nil {
            fmt.Println("BLPOP error")
            colorlog.Error(err.Error())
        }
        if results != nil {
            fmt.Println("Popped element belongs to list:", results[0])
            fmt.Println("Popped element's value:", results[1])
        } else {
            fmt.Println("Null list")
        }
    }()
    go func() {
        defer wg.Done()
        fmt.Println("Wait for 6 seconds:", time.Now().Format("2006/1/2 15:04:05"))
        time.Sleep(6 * time.Second)
        fmt.Println("RPUSH start:", time.Now().Format("2006/1/2 15:04:05"))
        rpushResult, err := redis.Int(c2.Do("RPUSH", "sun", "red"))
        if err != nil {
            fmt.Println("RPUSH error")
            colorlog.Error(err.Error())
        }
        fmt.Println("rpushResult:", rpushResult)
    }()
    wg.Wait()
}

Output

➤ go run main.go
Wait for 6 seconds: 2020/4/14 15:27:22
BLPOP start: 2020/4/14 15:27:22
RPUSH start: 2020/4/14 15:27:28
BLPOP end: 2020/4/14 15:27:28
Popped element belongs to list: sun
Popped element's value: red
rpushResult: 1

可以看到,BLPOP在22秒时开始,6秒之后,也就是28秒,RPUSH开始,也就在这一瞬间,List里有了元素,所以在28秒时BLPOP也就结束了,不会等到tiemout。

至于单独把这个阻塞的实验用另一个单独的函数来做,是因为需要两个redis.conn
在这个"github.com/garyburd/redigo/redis"包里,conn实现的Do()函数里,调用的DoWithTimeout()函数。
DoWithTimeout()函数里,conn是用了互斥锁的

func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
    return c.DoWithTimeout(c.readTimeout, cmd, args...)
}
func (c *conn) DoWithTimeout(readTimeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
    c.mu.Lock()
    pending := c.pending
    c.pending = 0
    c.mu.Unlock()
...

相关文章

  • Webpack 4 学习04(配置webpack-dev-ser

    前提:- Webpack 4 学习01(基础配置)​ - Webpack 4 学习02(...

  • webpack4入门学习笔记(一)

    系列博客链接 webpack4入门学习笔记(一) webpack4入门学习笔记(二) webpack4入门学习笔记...

  • webpack4入门学习笔记(二)

    系列博客链接 webpack4入门学习笔记(一) webpack4入门学习笔记(二) webpack4入门学习笔记...

  • webpack4入门学习笔记(三)--Babel的使用

    系列博客链接 webpack4入门学习笔记(一) webpack4入门学习笔记(二) webpack4入门学习笔记...

  • 学习4

    选择性粘贴 任意打开一张EXCEL表格。如图: 选择值,出现的结果就是下图: 如果选择格式,结果如下图: ctrl...

  • 4学习

    1.变化 2.设计B计划替代,减轻他焦虑,给他心里预期 3.让他说出b计划

  • 学习4

    看来三分钟的热度快到头了,学习也没有那么大的劲头了,看完一章基本上就不想再做习题了,就像快耗完油的汽车一样做着最后...

  • 学习-4

    BLPOP命令相关(BRPOP完全一样) List存在且长度大于0,返回key name和pop出来的元素 Lis...

  • 学习4

    今天学习王双雄老师第四课,新媒体精准引流的秘诀: 因为新媒体其实也很多。比如喜马拉雅音频矩阵系统,知乎等问答平台系...

  • 学习4

    1.对回避决定不服可向原审法院申请复议1次。 2.再审中,裁判文书是二审生效的或上级提审的,按二审程序组成合议庭审...

网友评论

      本文标题:学习-4

      本文链接:https://www.haomeiwen.com/subject/qactvhtx.html