ussd/internal/storage/timed.go
2024-10-02 22:06:43 +01:00

76 lines
1.4 KiB
Go

package storage
import (
"context"
"time"
"encoding/binary"
"git.defalsify.org/vise.git/db"
)
type TimedDb struct {
db.Db
tdb *SubPrefixDb
ttl time.Duration
parentPfx uint8
}
func NewTimedDb(db db.Db, ttl time.Duration) *TimedDb {
var b [2]byte
binary.BigEndian.PutUint16(b[:], SUBPREFIX_TIME)
sdb := NewSubPrefixDb(db, b[:])
return &TimedDb{
Db: db,
tdb: sdb,
ttl: ttl,
}
}
func(tib *TimedDb) SetPrefix(pfx uint8) {
tib.Db.SetPrefix(pfx)
tib.parentPfx = pfx
}
func(tib *TimedDb) Put(ctx context.Context, key []byte, val []byte) error {
t := time.Now()
b, err := t.MarshalBinary()
if err != nil {
return err
}
err = tib.Db.Put(ctx, key, val)
if err != nil {
return err
}
k := append([]byte{tib.parentPfx}, key...)
defer func() {
tib.parentPfx = 0
}()
err = tib.tdb.Put(ctx, k, b)
if err != nil {
logg.ErrorCtxf(ctx, "failed to update timestamp of record", err)
}
return nil
}
func(tib *TimedDb) Get(ctx context.Context, key []byte) ([]byte, error) {
v, err := tib.Db.Get(ctx, key)
return v, err
}
func(tib *TimedDb) Stale(ctx context.Context, pfx uint8, key []byte) bool {
b := append([]byte{pfx}, key...)
v, err := tib.tdb.Get(ctx, b)
if err != nil {
logg.ErrorCtxf(ctx, "no time entry", "key", key)
return false
}
t_now := time.Now()
t_then := time.Time{}
err = t_then.UnmarshalBinary(v)
if err != nil {
return false
}
return t_now.After(t_then.Add(tib.ttl))
}