Sunday, October 22, 2023

Go-Redis Pipeline for HGETALL



In this post we will show an example for using redis pipeline for HGETALL command.

I've found some examples out there on the web, but most of them cover only the update commands, and less referring to the read commands.


Let's start with creating a redis connection:


options := redis.Options{
Addr: "127.0.0.1:6379",
}
client := redis.NewClient(&options)


To handle the pipeline commands, we need to keep for each HGETALL command the pointer to the command, and only access it after the pipeline exec, hence we use a struct wrapper for this.


func ProducePipelineWrapper(
context context.Context,
origin redis.Pipeliner,
) *PipelineWrapper {
return &PipelineWrapper{
context: context,
origin: origin,
hGetAllCommands: make(map[string]*redis.MapStringStringCmd),
hGetAllResults: make(map[string]HGetAllResult),
}
}

func (p *PipelineWrapper) HGetAll(key string) {
p.hGetAllCommands[key] = p.origin.HGetAll(p.context, key)
}

func (p *PipelineWrapper) Exec() {
_, err := p.origin.Exec(p.context)
if err != nil {
panic(err)
}

for key, cmd := range p.hGetAllCommands {
result, err := cmd.Result()
if err != nil {
panic(err)
}
p.hGetAllResults[key] = result
}
}

func (p *PipelineWrapper) ResultsForHGetAll() map[string]HGetAllResult {
return p.hGetAllResults
}


To use this wrapper, we call HGETALL for a list of keys, and after the exec, we check the results.


wrapper := ProducePipelineWrapper(context.Background(), client.Pipeline())
keys := []string{"k1", "k2"}
for _, key := range keys {
wrapper.HGetAll(key)
}

wrapper.Exec()

for _, key := range keys {
values := wrapper.ResultsForHGetAll()[key]
fmt.Printf("key: %v, values: %v\n", key, values)
}


That's all folks!




No comments:

Post a Comment