mirror of
https://github.com/redis/go-redis.git
synced 2025-12-02 06:22:31 +03:00
autopipeline playground
This commit is contained in:
151
autopipeline_sequential_test.go
Normal file
151
autopipeline_sequential_test.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package redis_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
func TestAutoPipelineSequential(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
client := redis.NewClient(&redis.Options{
|
||||
Addr: ":6379",
|
||||
AutoPipelineConfig: &redis.AutoPipelineConfig{
|
||||
MaxBatchSize: 10,
|
||||
FlushInterval: 50 * time.Millisecond,
|
||||
MaxConcurrentBatches: 5,
|
||||
},
|
||||
})
|
||||
defer client.Close()
|
||||
|
||||
if err := client.FlushDB(ctx).Err(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ap := client.AutoPipeline()
|
||||
defer ap.Close()
|
||||
|
||||
// Sequential usage - no goroutines needed!
|
||||
// Commands will be queued and batched automatically
|
||||
cmds := make([]redis.Cmder, 20)
|
||||
for i := 0; i < 20; i++ {
|
||||
key := fmt.Sprintf("key%d", i)
|
||||
cmds[i] = ap.Do(ctx, "SET", key, i)
|
||||
}
|
||||
|
||||
// Now access results - this will block until commands execute
|
||||
for i, cmd := range cmds {
|
||||
if err := cmd.Err(); err != nil {
|
||||
t.Fatalf("Command %d failed: %v", i, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify all keys were set
|
||||
for i := 0; i < 20; i++ {
|
||||
key := fmt.Sprintf("key%d", i)
|
||||
val, err := client.Get(ctx, key).Int()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get %s: %v", key, err)
|
||||
}
|
||||
if val != i {
|
||||
t.Fatalf("Expected %d, got %d", i, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAutoPipelineSequentialSmallBatches(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
client := redis.NewClient(&redis.Options{
|
||||
Addr: ":6379",
|
||||
AutoPipelineConfig: &redis.AutoPipelineConfig{
|
||||
MaxBatchSize: 1000, // Large batch size
|
||||
FlushInterval: 20 * time.Millisecond, // Rely on timer
|
||||
MaxConcurrentBatches: 5,
|
||||
},
|
||||
})
|
||||
defer client.Close()
|
||||
|
||||
if err := client.FlushDB(ctx).Err(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ap := client.AutoPipeline()
|
||||
defer ap.Close()
|
||||
|
||||
// Queue commands sequentially with small delays
|
||||
// They should be flushed by timer, not batch size
|
||||
for i := 0; i < 5; i++ {
|
||||
key := fmt.Sprintf("key%d", i)
|
||||
cmd := ap.Do(ctx, "SET", key, i)
|
||||
|
||||
// Access result immediately - should block until flush
|
||||
if err := cmd.Err(); err != nil {
|
||||
t.Fatalf("Command %d failed: %v", i, err)
|
||||
}
|
||||
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
}
|
||||
|
||||
// Verify all keys were set
|
||||
for i := 0; i < 5; i++ {
|
||||
key := fmt.Sprintf("key%d", i)
|
||||
val, err := client.Get(ctx, key).Int()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get %s: %v", key, err)
|
||||
}
|
||||
if val != i {
|
||||
t.Fatalf("Expected %d, got %d", i, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAutoPipelineSequentialMixed(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
client := redis.NewClient(&redis.Options{
|
||||
Addr: ":6379",
|
||||
AutoPipelineConfig: &redis.AutoPipelineConfig{
|
||||
MaxBatchSize: 5,
|
||||
FlushInterval: 50 * time.Millisecond,
|
||||
MaxConcurrentBatches: 5,
|
||||
},
|
||||
})
|
||||
defer client.Close()
|
||||
|
||||
if err := client.FlushDB(ctx).Err(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ap := client.AutoPipeline()
|
||||
defer ap.Close()
|
||||
|
||||
// Queue some commands
|
||||
cmd1 := ap.Do(ctx, "SET", "key1", "value1")
|
||||
cmd2 := ap.Do(ctx, "SET", "key2", "value2")
|
||||
cmd3 := ap.Do(ctx, "SET", "key3", "value3")
|
||||
|
||||
// Access first result - should trigger batch flush
|
||||
if err := cmd1.Err(); err != nil {
|
||||
t.Fatalf("cmd1 failed: %v", err)
|
||||
}
|
||||
|
||||
// Other commands in same batch should also be done
|
||||
if err := cmd2.Err(); err != nil {
|
||||
t.Fatalf("cmd2 failed: %v", err)
|
||||
}
|
||||
if err := cmd3.Err(); err != nil {
|
||||
t.Fatalf("cmd3 failed: %v", err)
|
||||
}
|
||||
|
||||
// Verify
|
||||
val, err := client.Get(ctx, "key1").Result()
|
||||
if err != nil || val != "value1" {
|
||||
t.Fatalf("key1: expected value1, got %v, err %v", val, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user