Skip to content

Commit 06183e6

Browse files
committed
Merge branch 'master' of github.com:go-redis/redis
2 parents 217c470 + 157b164 commit 06183e6

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

cluster_commands.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package redis
22

33
import (
44
"context"
5+
"sync"
56
"sync/atomic"
67
)
78

@@ -23,3 +24,76 @@ func (c *ClusterClient) DBSize(ctx context.Context) *IntCmd {
2324
cmd.val = size
2425
return cmd
2526
}
27+
28+
func (c *ClusterClient) ScriptLoad(ctx context.Context, script string) *StringCmd {
29+
cmd := NewStringCmd(ctx, "script", "load", script)
30+
mu := &sync.Mutex{}
31+
err := c.ForEachShard(ctx, func(ctx context.Context, shard *Client) error {
32+
val, err := shard.ScriptLoad(ctx, script).Result()
33+
if err != nil {
34+
return err
35+
}
36+
37+
mu.Lock()
38+
if cmd.Val() == "" {
39+
cmd.val = val
40+
}
41+
mu.Unlock()
42+
43+
return nil
44+
})
45+
if err != nil {
46+
cmd.SetErr(err)
47+
}
48+
49+
return cmd
50+
}
51+
52+
func (c *ClusterClient) ScriptFlush(ctx context.Context) *StatusCmd {
53+
cmd := NewStatusCmd(ctx, "script", "flush")
54+
_ = c.ForEachShard(ctx, func(ctx context.Context, shard *Client) error {
55+
shard.ScriptFlush(ctx)
56+
57+
return nil
58+
})
59+
60+
return cmd
61+
}
62+
63+
func (c *ClusterClient) ScriptExists(ctx context.Context, hashes ...string) *BoolSliceCmd {
64+
args := make([]interface{}, 2+len(hashes))
65+
args[0] = "script"
66+
args[1] = "exists"
67+
for i, hash := range hashes {
68+
args[2+i] = hash
69+
}
70+
cmd := NewBoolSliceCmd(ctx, args...)
71+
72+
result := make([]bool, len(hashes))
73+
for i := range result {
74+
result[i] = true
75+
}
76+
77+
mu := &sync.Mutex{}
78+
err := c.ForEachShard(ctx, func(ctx context.Context, shard *Client) error {
79+
val, err := shard.ScriptExists(ctx, hashes...).Result()
80+
if err != nil {
81+
return err
82+
}
83+
84+
mu.Lock()
85+
for i, v := range val {
86+
result[i] = result[i] && v
87+
}
88+
mu.Unlock()
89+
90+
return nil
91+
})
92+
if err != nil {
93+
cmd.SetErr(err)
94+
}
95+
96+
cmd.val = result
97+
98+
return cmd
99+
}

cluster_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,50 @@ var _ = Describe("ClusterClient", func() {
344344
})
345345
})
346346

347+
It("distributes scripts when using Script Load", func() {
348+
client.ScriptFlush(ctx)
349+
350+
script := redis.NewScript(`return 'Unique script'`)
351+
352+
script.Load(ctx, client)
353+
354+
client.ForEachShard(ctx, func(ctx context.Context, shard *redis.Client) error {
355+
defer GinkgoRecover()
356+
357+
val, _ := script.Exists(ctx, shard).Result()
358+
Expect(val[0]).To(Equal(true))
359+
return nil
360+
})
361+
})
362+
363+
It("checks all shards when using Script Exists", func() {
364+
client.ScriptFlush(ctx)
365+
366+
script := redis.NewScript(`return 'First script'`)
367+
lostScriptSrc := `return 'Lost script'`
368+
lostScript := redis.NewScript(lostScriptSrc)
369+
370+
script.Load(ctx, client)
371+
client.Do(ctx, "script", "load", lostScriptSrc)
372+
373+
val, _ := client.ScriptExists(ctx, script.Hash(), lostScript.Hash()).Result()
374+
375+
Expect(val).To(Equal([]bool{true, false}))
376+
})
377+
378+
It("flushes scripts from all shards when using ScriptFlush", func() {
379+
script := redis.NewScript(`return 'Unnecessary script'`)
380+
script.Load(ctx, client)
381+
382+
val, _ := client.ScriptExists(ctx, script.Hash()).Result()
383+
Expect(val).To(Equal([]bool{true}))
384+
385+
client.ScriptFlush(ctx)
386+
387+
val, _ = client.ScriptExists(ctx, script.Hash()).Result()
388+
Expect(val).To(Equal([]bool{false}))
389+
})
390+
347391
It("supports Watch", func() {
348392
var incr func(string) error
349393

0 commit comments

Comments
 (0)