Skip to content
Snippets Groups Projects
Commit 8b087b50 authored by gjahn's avatar gjahn
Browse files

Add Redis as backing service to persist state

parent 0dc754e2
No related branches found
No related tags found
No related merge requests found
...@@ -12,6 +12,12 @@ type Config struct { ...@@ -12,6 +12,12 @@ type Config struct {
Environment string `env:"ENV_NAME" envDefault:"development"` Environment string `env:"ENV_NAME" envDefault:"development"`
Host string `env:"HOST" envDefault:"127.0.0.1"` Host string `env:"HOST" envDefault:"127.0.0.1"`
Port int16 `env:"PORT" envDefault:"3000"` Port int16 `env:"PORT" envDefault:"3000"`
DatabaseHost string `env:"DB_HOST" envDefault:""`
DatabasePort int16 `env:"DB_PORT" envDefault:"6379"`
DatabaseName int `env:"DB_NAME" envDefault:"0"`
DatabaseUsername string `env:"DB_USERNAME" envDefault:""`
DatabasePassword string `env:"DB_PASSWORD" envDefault:""`
} }
......
...@@ -6,12 +6,15 @@ require ( ...@@ -6,12 +6,15 @@ require (
github.com/caarlos0/env/v9 v9.0.0 github.com/caarlos0/env/v9 v9.0.0
github.com/go-playground/validator/v10 v10.15.5 github.com/go-playground/validator/v10 v10.15.5
github.com/gofiber/fiber/v2 v2.49.2 github.com/gofiber/fiber/v2 v2.49.2
github.com/redis/go-redis/v9 v9.3.0
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
) )
require ( require (
github.com/andybalholm/brotli v1.0.5 // indirect github.com/andybalholm/brotli v1.0.5 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
......
...@@ -2,9 +2,13 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/ ...@@ -2,9 +2,13 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/caarlos0/env/v9 v9.0.0 h1:SI6JNsOA+y5gj9njpgybykATIylrRMklbs5ch6wO6pc= github.com/caarlos0/env/v9 v9.0.0 h1:SI6JNsOA+y5gj9njpgybykATIylrRMklbs5ch6wO6pc=
github.com/caarlos0/env/v9 v9.0.0/go.mod h1:ye5mlCVMYh6tZ+vCgrs/B95sj88cg5Tlnc0XIzgZ020= github.com/caarlos0/env/v9 v9.0.0/go.mod h1:ye5mlCVMYh6tZ+vCgrs/B95sj88cg5Tlnc0XIzgZ020=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
...@@ -25,6 +29,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ ...@@ -25,6 +29,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0=
github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
......
...@@ -28,7 +28,12 @@ func main() { ...@@ -28,7 +28,12 @@ func main() {
DisableStartupMessage: config.Environment != "development", DisableStartupMessage: config.Environment != "development",
}) })
store := state.NewEphemeralStore() var store state.Store
if len( config.DatabaseHost ) <= 0 {
store = state.NewEphemeralStore()
} else {
store = state.NewPersistentStore( config )
}
var isHealthy = false var isHealthy = false
......
package state
import (
"fmt"
"runtime"
"context"
"time"
"webservice/configuration"
db "github.com/redis/go-redis/v9"
)
type Persistent struct {
client *db.Client
ctx context.Context
timeout time.Duration
}
func NewPersistentStore( c *configuration.Config ) *Persistent {
return &Persistent{
client: db.NewClient( &db.Options{
Addr: fmt.Sprintf( "%s:%d", c.DatabaseHost, c.DatabasePort ),
Username: c.DatabaseUsername,
Password: c.DatabasePassword,
DB: c.DatabaseName,
DialTimeout: time.Second * 3,
ContextTimeoutEnabled: true,
MaxRetries: 3,
MinRetryBackoff: time.Second * 1,
MaxRetryBackoff: time.Second * 2,
PoolSize: 10 * runtime.NumCPU(),
MaxActiveConns: 10 * runtime.NumCPU(),
}),
timeout: time.Second * 20,
}
}
func ( e *Persistent ) Add( i *Item ) error {
ctx, cancel := context.WithTimeout( context.TODO(), e.timeout )
defer cancel()
name := i.Name()
if err := e.client.HSet(
ctx, name,
"data", i.Data(),
"mime", i.MimeType(),
).Err(); err != nil {
return err
}
return nil
}
func ( e *Persistent ) Remove( name string ) error {
ctx, cancel := context.WithTimeout( context.TODO(), e.timeout )
defer cancel()
if err := e.client.Del( ctx, name ).Err(); err != nil {
return err
}
return nil
}
func ( e *Persistent ) Fetch( name string ) ( *Item, error ) {
ctx, cancel := context.WithTimeout( context.TODO(), e.timeout )
defer cancel()
value, err := e.client.HGetAll( ctx, name ).Result()
if err != nil {
return nil, err
}
var item *Item = nil
if len( value ) >= 1 {
item = NewItem( name, value[ "mime" ], []byte( value[ "data" ] ) )
}
return item, nil
}
func ( e *Persistent ) Show() ( []string, error ) {
ctx, cancel := context.WithTimeout( context.TODO(), e.timeout )
defer cancel()
var names []string
i := e.client.Scan( ctx, 0, "", 0 ).Iterator()
for i.Next( ctx ){
names = append( names, i.Val() )
}
if err := i.Err(); err != nil {
return nil, err
}
return names, nil
}
func ( e *Persistent ) Disconnect() error {
return e.client.Close()
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment