Last active
March 20, 2022 19:38
-
-
Save massenz/bd6c886f9236fd326478d9b560e13070 to your computer and use it in GitHub Desktop.
Serialize data to/from Redis in a custom type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"encoding/json" | |
"fmt" | |
"github.com/go-redis/redis/v8" | |
"os" | |
"time" | |
) | |
// Baby is a simple demo data struct | |
type Baby struct { | |
Name string | |
DateOfBirth time.Time | |
} | |
// MarshalBinary is needed to encode the data before storing in Redis, | |
// and to retrieve it later. | |
// | |
// **NOTE** the receiver must be a concrete type (NOT a pointer) of the | |
// serialization to Redis will fail. | |
func (i Baby) MarshalBinary() ([]byte, error) { | |
// Obviously it makes no sense to serialize to JSON to store in Redis, | |
// but the same approach would work with, for example, Protobuf messages | |
// with an efficent binary encoding. | |
return json.Marshal(i) | |
} | |
// UnmarshalBinary is the dual of MarshalBinary and will parse the | |
// binary data into the receiver. | |
// See: https://pkg.go.dev/encoding | |
func (i *Baby) UnmarshalBinary(data []byte) error { | |
return json.Unmarshal(data, i) | |
} | |
func main() { | |
// To run Redis as a container, see: https://hub.docker.com/_/redis/ | |
// | |
// To connect from the client, see: | |
// https://redis.uptrace.dev/guide/server.html#connecting-to-redis-server | |
rdb := redis.NewClient(&redis.Options{ | |
Addr: "localhost:6379", | |
Password: "", // no password set | |
DB: 0, // use default DB | |
}) | |
// Creates a Context which will time out after 200ms | |
// See: https://go.dev/blog/context | |
timeout, _ := time.ParseDuration("200ms") | |
ctx, cancel := context.WithTimeout(context.Background(), timeout) | |
defer cancel() | |
// Congratulations to mum & dad! | |
baby := Baby{ | |
Name: "Charlie", | |
DateOfBirth: time.Now(), | |
} | |
start := time.Now() | |
cmd := rdb.Set(ctx, "charlie", baby, timeout) | |
val, err := cmd.Result() | |
if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} | |
// This will just emit `OK` | |
fmt.Println(val) | |
getCmd := rdb.Get(ctx, "charlie") | |
data, err := getCmd.Bytes() | |
if err == redis.Nil { | |
fmt.Println("No babies found!") | |
} else if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} else { | |
var baby Baby | |
err = baby.UnmarshalBinary(data) | |
if err != nil { | |
fmt.Println(err) | |
os.Exit(1) | |
} | |
fmt.Println(baby) | |
} | |
fmt.Printf("Took %q\n", time.Since(start)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment