Change keyvalue.Get to return if a value exists or not instead of an error

This commit is contained in:
kolaente 2021-01-31 12:32:46 +01:00
parent fe72f30b24
commit 2e88600c93
Signed by untrusted user: konrad
GPG Key ID: F40E70337AB24C9B
9 changed files with 28 additions and 43 deletions

View File

@ -91,7 +91,7 @@ func SetUserActive(a web.Auth) (err error) {
// getActiveUsers returns the active users from redis // getActiveUsers returns the active users from redis
func getActiveUsers() (users activeUsersMap, err error) { func getActiveUsers() (users activeUsersMap, err error) {
u, err := keyvalue.Get(ActiveUsersKey) u, _, err := keyvalue.Get(ActiveUsersKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -20,7 +20,6 @@ import (
"code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/modules/keyvalue" "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"
"github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promauto"
) )
@ -97,13 +96,14 @@ func InitMetrics() {
// GetCount returns the current count from redis // GetCount returns the current count from redis
func GetCount(key string) (count int64, err error) { func GetCount(key string) (count int64, err error) {
cnt, err := keyvalue.Get(key) cnt, exists, err := keyvalue.Get(key)
if err != nil { if err != nil {
if e.IsErrValueNotFoundForKey(err) {
return 0, nil
}
return 0, err return 0, err
} }
if !exists {
return 0, nil
}
count = cnt.(int64) count = cnt.(int64)
return return

View File

@ -24,7 +24,6 @@ import (
"code.vikunja.io/api/pkg/config" "code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/modules/keyvalue" "code.vikunja.io/api/pkg/modules/keyvalue"
kerr "code.vikunja.io/api/pkg/modules/keyvalue/error"
"github.com/coreos/go-oidc" "github.com/coreos/go-oidc"
"golang.org/x/oauth2" "golang.org/x/oauth2"
) )
@ -35,8 +34,8 @@ func GetAllProviders() (providers []*Provider, err error) {
return nil, nil return nil, nil
} }
ps, err := keyvalue.Get("openid_providers") ps, exists, err := keyvalue.Get("openid_providers")
if err != nil && kerr.IsErrValueNotFoundForKey(err) { if !exists {
rawProviders := config.AuthOpenIDProviders.Get() rawProviders := config.AuthOpenIDProviders.Get()
if rawProviders == nil { if rawProviders == nil {
return nil, nil return nil, nil
@ -73,14 +72,14 @@ func GetAllProviders() (providers []*Provider, err error) {
// GetProvider retrieves a provider from keyvalue // GetProvider retrieves a provider from keyvalue
func GetProvider(key string) (provider *Provider, err error) { func GetProvider(key string) (provider *Provider, err error) {
var p interface{} var p interface{}
p, err = keyvalue.Get("openid_provider_" + key) p, exists, err := keyvalue.Get("openid_provider_" + key)
if err != nil && kerr.IsErrValueNotFoundForKey(err) { if exists {
_, err = GetAllProviders() // This will put all providers in cache _, err = GetAllProviders() // This will put all providers in cache
if err != nil { if err != nil {
return nil, err return nil, err
} }
p, err = keyvalue.Get("openid_provider_" + key) p, _, err = keyvalue.Get("openid_provider_" + key)
} }
if p != nil { if p != nil {

View File

@ -27,7 +27,6 @@ import (
"code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/modules/keyvalue" "code.vikunja.io/api/pkg/modules/keyvalue"
e "code.vikunja.io/api/pkg/modules/keyvalue/error"
"code.vikunja.io/api/pkg/user" "code.vikunja.io/api/pkg/user"
"github.com/disintegration/imaging" "github.com/disintegration/imaging"
"github.com/golang/freetype/truetype" "github.com/golang/freetype/truetype"
@ -128,12 +127,12 @@ func getCacheKey(prefix string, keys ...int64) string {
func getAvatarForUser(u *user.User) (fullSizeAvatar *image.RGBA64, err error) { func getAvatarForUser(u *user.User) (fullSizeAvatar *image.RGBA64, err error) {
cacheKey := getCacheKey("full", u.ID) cacheKey := getCacheKey("full", u.ID)
a, err := keyvalue.Get(cacheKey) a, exists, err := keyvalue.Get(cacheKey)
if err != nil && !e.IsErrValueNotFoundForKey(err) { if err != nil {
return nil, err return nil, err
} }
if err != nil && e.IsErrValueNotFoundForKey(err) { if !exists {
log.Debugf("Initials avatar for user %d not cached, creating...", u.ID) log.Debugf("Initials avatar for user %d not cached, creating...", u.ID)
firstRune := []rune(strings.ToUpper(u.Username))[0] firstRune := []rune(strings.ToUpper(u.Username))[0]
bg := avatarBgColors[int(u.ID)%len(avatarBgColors)] // Random color based on the user id bg := avatarBgColors[int(u.ID)%len(avatarBgColors)] // Random color based on the user id
@ -157,12 +156,12 @@ func getAvatarForUser(u *user.User) (fullSizeAvatar *image.RGBA64, err error) {
func (p *Provider) GetAvatar(u *user.User, size int64) (avatar []byte, mimeType string, err error) { func (p *Provider) GetAvatar(u *user.User, size int64) (avatar []byte, mimeType string, err error) {
cacheKey := getCacheKey("resized", u.ID, size) cacheKey := getCacheKey("resized", u.ID, size)
a, err := keyvalue.Get(cacheKey) a, exists, err := keyvalue.Get(cacheKey)
if err != nil && !e.IsErrValueNotFoundForKey(err) { if err != nil {
return nil, "", err return nil, "", err
} }
if err != nil && e.IsErrValueNotFoundForKey(err) { if !exists {
log.Debugf("Initials avatar for user %d and size %d not cached, creating...", u.ID, size) log.Debugf("Initials avatar for user %d and size %d not cached, creating...", u.ID, size)
fullAvatar, err := getAvatarForUser(u) fullAvatar, err := getAvatarForUser(u)
if err != nil { if err != nil {

View File

@ -26,7 +26,6 @@ import (
"code.vikunja.io/api/pkg/files" "code.vikunja.io/api/pkg/files"
"code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/modules/keyvalue" "code.vikunja.io/api/pkg/modules/keyvalue"
e "code.vikunja.io/api/pkg/modules/keyvalue/error"
"code.vikunja.io/api/pkg/user" "code.vikunja.io/api/pkg/user"
"github.com/disintegration/imaging" "github.com/disintegration/imaging"
) )
@ -40,8 +39,8 @@ func (p *Provider) GetAvatar(u *user.User, size int64) (avatar []byte, mimeType
cacheKey := "avatar_upload_" + strconv.Itoa(int(u.ID)) cacheKey := "avatar_upload_" + strconv.Itoa(int(u.ID))
ai, err := keyvalue.Get(cacheKey) ai, exists, err := keyvalue.Get(cacheKey)
if err != nil && !e.IsErrValueNotFoundForKey(err) { if err != nil {
return nil, "", err return nil, "", err
} }
@ -51,7 +50,7 @@ func (p *Provider) GetAvatar(u *user.User, size int64) (avatar []byte, mimeType
cached = ai.(map[int64][]byte) cached = ai.(map[int64][]byte)
} }
if err != nil && e.IsErrValueNotFoundForKey(err) { if !exists {
// Nothing ever cached for this user so we need to create the size map to avoid panics // Nothing ever cached for this user so we need to create the size map to avoid panics
cached = make(map[int64][]byte) cached = make(map[int64][]byte)
} else { } else {

View File

@ -34,7 +34,6 @@ import (
"code.vikunja.io/api/pkg/models" "code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/modules/background" "code.vikunja.io/api/pkg/modules/background"
"code.vikunja.io/api/pkg/modules/keyvalue" "code.vikunja.io/api/pkg/modules/keyvalue"
e "code.vikunja.io/api/pkg/modules/keyvalue/error"
"code.vikunja.io/web" "code.vikunja.io/web"
) )
@ -123,12 +122,12 @@ func getImageID(fullURL string) string {
// Gets an unsplash photo either from cache or directly from the unsplash api // Gets an unsplash photo either from cache or directly from the unsplash api
func getUnsplashPhotoInfoByID(photoID string) (photo *Photo, err error) { func getUnsplashPhotoInfoByID(photoID string) (photo *Photo, err error) {
p, err := keyvalue.Get(cachePrefix + photoID) p, exists, err := keyvalue.Get(cachePrefix + photoID)
if err != nil && !e.IsErrValueNotFoundForKey(err) { if err != nil {
return nil, err return nil, err
} }
if err != nil && e.IsErrValueNotFoundForKey(err) { if !exists {
log.Debugf("Image information for unsplash photo %s not cached, requesting from unsplash...", photoID) log.Debugf("Image information for unsplash photo %s not cached, requesting from unsplash...", photoID)
photo = &Photo{} photo = &Photo{}
err = doGet("photos/"+photoID, photo) err = doGet("photos/"+photoID, photo)

View File

@ -25,7 +25,7 @@ import (
// Storage defines an interface for saving key-value pairs // Storage defines an interface for saving key-value pairs
type Storage interface { type Storage interface {
Put(key string, value interface{}) (err error) Put(key string, value interface{}) (err error)
Get(key string) (value interface{}, err error) Get(key string) (value interface{}, exists bool, err error)
Del(key string) (err error) Del(key string) (err error)
IncrBy(key string, update int64) (err error) IncrBy(key string, update int64) (err error)
DecrBy(key string, update int64) (err error) DecrBy(key string, update int64) (err error)
@ -51,7 +51,7 @@ func Put(key string, value interface{}) error {
} }
// Get returns a value from a storage backend // Get returns a value from a storage backend
func Get(key string) (value interface{}, err error) { func Get(key string) (value interface{}, exists bool, err error) {
return store.Get(key) return store.Get(key)
} }

View File

@ -44,16 +44,11 @@ func (s *Storage) Put(key string, value interface{}) (err error) {
} }
// Get retrieves a saved value from memory storage // Get retrieves a saved value from memory storage
func (s *Storage) Get(key string) (value interface{}, err error) { func (s *Storage) Get(key string) (value interface{}, exists bool, err error) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
var exists bool
value, exists = s.store[key] value, exists = s.store[key]
if !exists {
return nil, &e.ErrValueNotFoundForKey{Key: key}
}
return return
} }

View File

@ -20,9 +20,6 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"github.com/go-errors/errors"
e "code.vikunja.io/api/pkg/modules/keyvalue/error"
"code.vikunja.io/api/pkg/red" "code.vikunja.io/api/pkg/red"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
) )
@ -52,13 +49,10 @@ func (s *Storage) Put(key string, value interface{}) (err error) {
} }
// Get retrieves a saved value from redis // Get retrieves a saved value from redis
func (s *Storage) Get(key string) (value interface{}, err error) { func (s *Storage) Get(key string) (value interface{}, exists bool, err error) {
b, err := s.client.Get(context.Background(), key).Bytes() b, err := s.client.Get(context.Background(), key).Bytes()
if err != nil { if err != nil {
if errors.Is(err, redis.Nil) { return nil, false, err
return nil, &e.ErrValueNotFoundForKey{Key: key}
}
return nil, err
} }
err = json.Unmarshal(b, value) err = json.Unmarshal(b, value)