start to move session stores into there own key value in memory store

This commit is contained in:
Gregory Wells
2026-06-08 18:16:07 -04:00
parent 3b31adf3e2
commit f6016bbdb1
9 changed files with 62 additions and 60 deletions
+10
View File
@@ -0,0 +1,10 @@
package store
// A simple key value store that can either just be single instance in memory or a redis server (for now)
type Store[Value any] interface {
Create(key string, value Value) error
Get(key string) (Value, error)
Update(key string, session Value) error
Delete(key string) error
}
+8
View File
@@ -0,0 +1,8 @@
package store
import "errors"
var ErrKeyNotFound = errors.New("Key not found")
var ErrKeyAlreadyExists = errors.New("Key already exists")
var ErrKeyExpired = errors.New("Key expired")
var ErrKeyBackend = errors.New("Key backend")
+11
View File
@@ -0,0 +1,11 @@
package store
import (
"crypto/sha256"
"encoding/base64"
)
func HashKey(key string) string {
tokenEncoded := sha256.Sum256([]byte(key))
return base64.RawURLEncoding.EncodeToString(tokenEncoded[:])
}
+116
View File
@@ -0,0 +1,116 @@
package store
import (
"context"
"encoding/json"
"time"
"astraltech.xyz/accountmanager/src/logging"
"github.com/redis/go-redis/v9"
)
type RedisStore[Value any] struct {
client *redis.Client
ctx context.Context
prefix string
}
func (m *RedisStore[Value]) RedisHash(value_to_hash string) string {
return m.prefix + HashKey(value_to_hash)
}
func NewRedisStore[Value any]() *RedisStore[Value] {
logging.Debug("Creating new redis session store")
// this will be replaced with a URL that can be parsed in the config file
redis_server := "redis://localhost:6379/0"
opts, err := redis.ParseURL(redis_server)
if err != nil {
logging.Errorf("Failed to parse redis url %s", err.Error())
}
rdb := redis.NewClient(opts)
ctx := context.Background()
if err := rdb.Ping(ctx).Err(); err != nil {
logging.Errorf("Failed to connect to redis server %s", redis_server)
} else {
logging.Infof("Successfully connected to redis server %s", redis_server)
}
store := &RedisStore[Value]{
client: rdb,
ctx: ctx,
}
return store
}
func (m *RedisStore[Value]) Create(key string, value Value) (err error) {
hashedSession := m.RedisHash(key)
data, err := json.Marshal(value)
if err != nil {
return ErrKeyBackend
}
created, err := m.client.SetNX(m.ctx, hashedSession, data, time.Hour).Result()
if err != nil {
logging.Error(err.Error())
return ErrKeyBackend
}
if !created {
return ErrKeyAlreadyExists
}
return nil
}
func (m *RedisStore[Value]) Get(sessionID string) (Value, error) {
hashed := m.RedisHash(sessionID)
var session_data Value
data, err := m.client.Get(m.ctx, hashed).Bytes()
if err == redis.Nil {
return session_data, ErrKeyNotFound
} else if err != nil {
logging.Error(err.Error())
return session_data, ErrKeyBackend
}
if err := json.Unmarshal(data, session_data); err != nil {
logging.Error(err.Error())
return session_data, ErrKeyBackend
}
return session_data, nil
}
func (m *RedisStore[Value]) Update(key string, value Value) error {
hashedSession := m.RedisHash(key)
data, err := json.Marshal(value)
if err != nil {
return ErrKeyBackend
}
updated, err := m.client.SetXX(m.ctx, hashedSession, data, time.Hour).Result()
if err != nil {
logging.Error(err.Error())
return ErrKeyBackend
}
if !updated {
return ErrKeyNotFound
}
return nil
}
func (m *RedisStore[Value]) Delete(sessionID string) error {
hashedSession := m.RedisHash(sessionID)
err := m.client.Del(m.ctx, hashedSession).Err()
if err != nil {
logging.Error(err.Error())
return ErrKeyBackend
}
return nil
}