...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package redis_test
16
17 import (
18 "fmt"
19
20 "github.com/gomodule/redigo/redis"
21 )
22
23
24 func zpop(c redis.Conn, key string) (result string, err error) {
25
26 defer func() {
27
28 if err != nil {
29 c.Do("DISCARD")
30 }
31 }()
32
33
34 for {
35 if _, err := c.Do("WATCH", key); err != nil {
36 return "", err
37 }
38
39 members, err := redis.Strings(c.Do("ZRANGE", key, 0, 0))
40 if err != nil {
41 return "", err
42 }
43 if len(members) != 1 {
44 return "", redis.ErrNil
45 }
46
47 c.Send("MULTI")
48 c.Send("ZREM", key, members[0])
49 queued, err := c.Do("EXEC")
50 if err != nil {
51 return "", err
52 }
53
54 if queued != nil {
55 result = members[0]
56 break
57 }
58 }
59
60 return result, nil
61 }
62
63
64 var zpopScript = redis.NewScript(1, `
65 local r = redis.call('ZRANGE', KEYS[1], 0, 0)
66 if r ~= nil then
67 r = r[1]
68 redis.call('ZREM', KEYS[1], r)
69 end
70 return r
71 `)
72
73
74
75 func Example_zpop() {
76 c, err := dial()
77 if err != nil {
78 fmt.Println(err)
79 return
80 }
81 defer c.Close()
82
83
84
85 for i, member := range []string{"red", "blue", "green"} {
86 c.Send("ZADD", "zset", i, member)
87 }
88 if _, err := c.Do(""); err != nil {
89 fmt.Println(err)
90 return
91 }
92
93
94
95 v, err := zpop(c, "zset")
96 if err != nil {
97 fmt.Println(err)
98 return
99 }
100 fmt.Println(v)
101
102
103
104 v, err = redis.String(zpopScript.Do(c, "zset"))
105 if err != nil {
106 fmt.Println(err)
107 return
108 }
109 fmt.Println(v)
110
111
112
113
114 }
115
View as plain text