Skip to content

Commit

Permalink
DOC-4560 pipelines/transactions example (redis#3202)
Browse files Browse the repository at this point in the history
* DOC-4560 basic transaction example

* DOC-4560 added pipe/transaction examples
  • Loading branch information
andy-stark-redis authored Jan 17, 2025
1 parent e953b76 commit f3a15c4
Showing 1 changed file with 180 additions and 0 deletions.
180 changes: 180 additions & 0 deletions doctests/pipe_trans_example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// EXAMPLE: pipe_trans_tutorial
// HIDE_START
package example_commands_test

import (
"context"
"fmt"

"github.com/redis/go-redis/v9"
)

// HIDE_END

func ExampleClient_transactions() {
ctx := context.Background()

rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password docs
DB: 0, // use default DB
})
// REMOVE_START
for i := 0; i < 5; i++ {
rdb.Del(ctx, fmt.Sprintf("seat:%d", i))
}

rdb.Del(ctx, "counter:1", "counter:2", "counter:3", "shellpath")
// REMOVE_END

// STEP_START basic_pipe
pipe := rdb.Pipeline()

for i := 0; i < 5; i++ {
pipe.Set(ctx, fmt.Sprintf("seat:%v", i), fmt.Sprintf("#%v", i), 0)
}

cmds, err := pipe.Exec(ctx)

if err != nil {
panic(err)
}

for _, c := range cmds {
fmt.Printf("%v;", c.(*redis.StatusCmd).Val())
}

fmt.Println("")
// >>> OK;OK;OK;OK;OK;

pipe = rdb.Pipeline()

get0Result := pipe.Get(ctx, "seat:0")
get3Result := pipe.Get(ctx, "seat:3")
get4Result := pipe.Get(ctx, "seat:4")

cmds, err = pipe.Exec(ctx)

// The results are available only after the pipeline
// has finished executing.
fmt.Println(get0Result.Val()) // >>> #0
fmt.Println(get3Result.Val()) // >>> #3
fmt.Println(get4Result.Val()) // >>> #4
// STEP_END

// STEP_START basic_pipe_pipelined
var pd0Result *redis.StatusCmd
var pd3Result *redis.StatusCmd
var pd4Result *redis.StatusCmd

cmds, err = rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
pd0Result = (*redis.StatusCmd)(pipe.Get(ctx, "seat:0"))
pd3Result = (*redis.StatusCmd)(pipe.Get(ctx, "seat:3"))
pd4Result = (*redis.StatusCmd)(pipe.Get(ctx, "seat:4"))
return nil
})

if err != nil {
panic(err)
}

// The results are available only after the pipeline
// has finished executing.
fmt.Println(pd0Result.Val()) // >>> #0
fmt.Println(pd3Result.Val()) // >>> #3
fmt.Println(pd4Result.Val()) // >>> #4
// STEP_END

// STEP_START basic_trans
trans := rdb.TxPipeline()

trans.IncrBy(ctx, "counter:1", 1)
trans.IncrBy(ctx, "counter:2", 2)
trans.IncrBy(ctx, "counter:3", 3)

cmds, err = trans.Exec(ctx)

for _, c := range cmds {
fmt.Println(c.(*redis.IntCmd).Val())
}
// >>> 1
// >>> 2
// >>> 3
// STEP_END

// STEP_START basic_trans_txpipelined
var tx1Result *redis.IntCmd
var tx2Result *redis.IntCmd
var tx3Result *redis.IntCmd

cmds, err = rdb.TxPipelined(ctx, func(trans redis.Pipeliner) error {
tx1Result = trans.IncrBy(ctx, "counter:1", 1)
tx2Result = trans.IncrBy(ctx, "counter:2", 2)
tx3Result = trans.IncrBy(ctx, "counter:3", 3)
return nil
})

if err != nil {
panic(err)
}

fmt.Println(tx1Result.Val()) // >>> 2
fmt.Println(tx2Result.Val()) // >>> 4
fmt.Println(tx3Result.Val()) // >>> 6
// STEP_END

// STEP_START trans_watch
// Set initial value of `shellpath`.
rdb.Set(ctx, "shellpath", "/usr/syscmds/", 0)

const maxRetries = 1000

// Retry if the key has been changed.
for i := 0; i < maxRetries; i++ {
err := rdb.Watch(ctx,
func(tx *redis.Tx) error {
currentPath, err := rdb.Get(ctx, "shellpath").Result()
newPath := currentPath + ":/usr/mycmds/"

_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Set(ctx, "shellpath", newPath, 0)
return nil
})

return err
},
"shellpath",
)

if err == nil {
// Success.
break
} else if err == redis.TxFailedErr {
// Optimistic lock lost. Retry the transaction.
continue
} else {
// Panic for any other error.
panic(err)
}
}

fmt.Println(rdb.Get(ctx, "shellpath").Val())
// >>> /usr/syscmds/:/usr/mycmds/
// STEP_END

// Output:
// OK;OK;OK;OK;OK;
// #0
// #3
// #4
// #0
// #3
// #4
// 1
// 2
// 3
// 2
// 4
// 6
// /usr/syscmds/:/usr/mycmds/
}

0 comments on commit f3a15c4

Please sign in to comment.