1
0

Key-Value Storages (#674)

Fix lint

Add docs for keyvalue config options

Use keyvalue store to cache unsplash photo results

Cleanup

Use keyvalue store for upload avatar

Use keyvalue store for initials avatar

Fix initializing metrics

Use keyvalue for metrics

Add IncryBy and DecrBy methods to increase or decrease a value

Fix lint

Return custom error if a key does not exist

Init keyvalue storage

Follow the keyvalue storage setting for things like cache and other

Add docs

Add configuration of the storage backend

Add redis keyvalue storage implementation

Add doc comments

Add methods to use storage through the package itself

Add memory implementation for keyvalue store

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/674
Co-Authored-By: konrad <konrad@kola-entertainments.de>
Co-Committed-By: konrad <konrad@kola-entertainments.de>
This commit is contained in:
konrad
2020-10-10 16:53:59 +00:00
parent bf5d8af3f6
commit d56a611be7
16 changed files with 469 additions and 122 deletions

View File

@ -17,10 +17,9 @@
package metrics
import (
"bytes"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/modules/keyvalue"
"code.vikunja.io/web"
"encoding/gob"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"sync"
@ -91,36 +90,19 @@ func SetUserActive(a web.Auth) (err error) {
// getActiveUsers returns the active users from redis
func getActiveUsers() (users activeUsersMap, err error) {
activeUsersR, err := r.Get(ActiveUsersKey).Bytes()
if err != nil {
if err.Error() == "redis: nil" {
return users, nil
}
return
}
var b bytes.Buffer
_, err = b.Write(activeUsersR)
u, err := keyvalue.Get(ActiveUsersKey)
if err != nil {
return nil, err
}
d := gob.NewDecoder(&b)
if err := d.Decode(&users); err != nil {
return nil, err
}
users = u.(activeUsersMap)
return
}
// PushActiveUsers pushed the content of the activeUsers map to redis
func PushActiveUsers() (err error) {
var b bytes.Buffer
e := gob.NewEncoder(&b)
activeUsers.mutex.Lock()
defer activeUsers.mutex.Unlock()
if err := e.Encode(activeUsers.users); err != nil {
return err
}
return r.Set(ActiveUsersKey, b.Bytes(), 0).Err()
return keyvalue.Put(ActiveUsersKey, activeUsers.users)
}

View File

@ -19,14 +19,12 @@ package metrics
import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/red"
"github.com/go-redis/redis/v7"
"code.vikunja.io/api/pkg/modules/keyvalue"
e "code.vikunja.io/api/pkg/modules/keyvalue/error"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var r *redis.Client
const (
// ListCountKey is the name of the key in which we save the list count
ListCountKey = `listcount`
@ -46,8 +44,6 @@ const (
// InitMetrics Initializes the metrics
func InitMetrics() {
r = red.GetRedis()
// init active users, sometimes we'll have garbage from previous runs in redis instead
if err := PushActiveUsers(); err != nil {
log.Fatalf("Could not set initial count for active users, error was %s", err)
@ -101,18 +97,21 @@ func InitMetrics() {
// GetCount returns the current count from redis
func GetCount(key string) (count int64, err error) {
count, err = r.Get(key).Int64()
if err != nil && err.Error() != "redis: nil" {
return
cnt, err := keyvalue.Get(key)
if err != nil {
if e.IsErrValueNotFoundForKey(err) {
return 0, nil
}
return 0, err
}
err = nil
count = cnt.(int64)
return
}
// SetCount sets the list count to a given value
func SetCount(count int64, key string) error {
return r.Set(key, count, 0).Err()
return keyvalue.Put(key, count)
}
// UpdateCount updates a count with a given amount
@ -121,13 +120,13 @@ func UpdateCount(update int64, key string) {
return
}
if update > 0 {
err := r.IncrBy(key, update).Err()
err := keyvalue.IncrBy(key, update)
if err != nil {
log.Error(err.Error())
}
}
if update < 0 {
err := r.DecrBy(key, update).Err()
err := keyvalue.DecrBy(key, update)
if err != nil {
log.Error(err.Error())
}