♻️ Refactored with new cache system

This commit is contained in:
2024-09-22 13:45:02 +08:00
parent 560c8a9143
commit db57e4764c
5 changed files with 507 additions and 44 deletions

24
pkg/internal/cache/store.go vendored Normal file
View File

@ -0,0 +1,24 @@
package cache
import (
"github.com/dgraph-io/ristretto"
"github.com/eko/gocache/lib/v4/store"
ristrettoCache "github.com/eko/gocache/store/ristretto/v4"
)
var S store.StoreInterface
func NewStore() error {
ristretto, err := ristretto.NewCache(&ristretto.Config{
NumCounters: 1000,
MaxCost: 100,
BufferItems: 64,
})
if err != nil {
return err
}
S = ristrettoCache.NewRistretto(ristretto)
return nil
}

View File

@ -1,30 +1,33 @@
package services
import (
"context"
"fmt"
"math"
"mime"
"mime/multipart"
"net/http"
"path/filepath"
"strconv"
"sync"
"time"
"github.com/eko/gocache/lib/v4/cache"
"github.com/eko/gocache/lib/v4/marshaler"
"github.com/eko/gocache/lib/v4/store"
"github.com/spf13/viper"
"gorm.io/datatypes"
"git.solsynth.dev/hydrogen/dealer/pkg/hyper"
localCache "git.solsynth.dev/hydrogen/paperclip/pkg/internal/cache"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/database"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/models"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
"gorm.io/gorm"
)
const metadataCacheLimit = 512
var metadataCache sync.Map
func GetAttachmentCacheKey(rid string) any {
return fmt.Sprintf("attachment#%s", rid)
}
func GetAttachmentByID(id uint) (models.Attachment, error) {
var attachment models.Attachment
@ -41,8 +44,18 @@ func GetAttachmentByID(id uint) (models.Attachment, error) {
}
func GetAttachmentByRID(rid string) (models.Attachment, error) {
if val, ok := metadataCache.Load(rid); ok && val.(models.Attachment).Account.ID > 0 {
return val.(models.Attachment), nil
cacheManager := cache.New[any](localCache.S)
marshal := marshaler.New(cacheManager)
contx := context.Background()
if val, err := marshal.Get(
contx,
GetAttachmentCacheKey(rid),
new(models.Attachment),
); err == nil {
if val.(models.Attachment).Account.ID > 0 {
return val.(models.Attachment), nil
}
}
var attachment models.Attachment
@ -67,16 +80,35 @@ func GetAttachmentByHash(hash string) (models.Attachment, error) {
return attachment, nil
}
func GetAttachmentCache(id any) (models.Attachment, bool) {
if val, ok := metadataCache.Load(id); ok && val.(models.Attachment).Account.ID > 0 {
return val.(models.Attachment), ok
func GetAttachmentCache(rid string) (models.Attachment, bool) {
cacheManager := cache.New[any](localCache.S)
marshal := marshaler.New(cacheManager)
contx := context.Background()
if val, err := marshal.Get(
contx,
GetAttachmentCacheKey(rid),
new(models.Attachment),
); err == nil {
if val.(models.Attachment).Account.ID > 0 {
return val.(models.Attachment), true
}
}
return models.Attachment{}, false
}
func CacheAttachment(item models.Attachment) {
MaintainAttachmentCache()
metadataCache.Store(item.Rid, item)
cacheManager := cache.New[any](localCache.S)
marshal := marshaler.New(cacheManager)
contx := context.Background()
marshal.Set(
contx,
GetAttachmentCacheKey(item.Rid),
item,
store.WithExpiration(60*time.Minute),
store.WithTags([]string{"attachment", fmt.Sprintf("user#%d", item.AccountID)}),
)
}
func NewAttachmentMetadata(tx *gorm.DB, user models.Account, file *multipart.FileHeader, attachment models.Attachment) (models.Attachment, error) {
@ -216,9 +248,10 @@ func DeleteAttachment(item models.Attachment) error {
tx.Rollback()
return err
} else {
strId := strconv.Itoa(int(item.ID))
metadataCache.Delete(strId)
metadataCache.Delete(item.Rid)
cacheManager := cache.New[any](localCache.S)
marshal := marshaler.New(cacheManager)
contx := context.Background()
marshal.Delete(contx, GetAttachmentCacheKey(item.Rid))
}
tx.Commit()
@ -229,19 +262,3 @@ func DeleteAttachment(item models.Attachment) error {
return nil
}
func MaintainAttachmentCache() {
var keySet []any
metadataCache.Range(func(k any, v any) bool {
keySet = append(keySet, k)
return true
})
if len(keySet) > metadataCacheLimit {
go func() {
log.Debug().Int("count", len(keySet)).Msg("Cleaning attachment metadata cache...")
for _, k := range keySet {
metadataCache.Delete(k)
}
}()
}
}

View File

@ -5,6 +5,7 @@ import (
"os/signal"
"syscall"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/cache"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/database"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/gap"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/grpc"
@ -43,6 +44,11 @@ func main() {
log.Fatal().Err(err).Msg("An error occurred when running database auto migration.")
}
// Initialize cache
if err := cache.NewStore(); err != nil {
log.Fatal().Err(err).Msg("An error occurred when initializing cache.")
}
// Connect other services
if err := gap.RegisterService(); err != nil {
log.Error().Err(err).Msg("An error occurred when registering service to dealer...")