cache/repo.go

86 lines
1.8 KiB
Go

package cache
import (
"context"
"encoding/gob"
"os"
"path/filepath"
"time"
"git.belvedersky.ru/common/logger"
"git.belvedersky.ru/common/logger/service"
badger "github.com/dgraph-io/badger/v3"
)
type CacheConfig struct {
Dir string
}
type CacheRepository struct {
cache *badger.DB
logger *service.LoggerService
config *CacheConfig
Err service.TypeError
}
// Новый сервис кеша
func New(config *CacheConfig, l *logger.Logger) (repo *CacheRepository, err error) {
path := filepath.Join(".", config.Dir)
if _, err = os.Stat(path); os.IsNotExist(err) {
err := os.Mkdir(path, 0777)
if err != nil {
return nil, err
}
}
cacheConfig := badger.DefaultOptions(config.Dir)
log := l.Create("cache")
cacheConfig.Logger = log
cache, err := badger.Open(cacheConfig.WithLoggingLevel(badger.ERROR))
if err != nil {
return nil, err
}
r := CacheRepository{
config: config,
cache: cache,
Err: service.TypeError{Code: 3, Description: "Ошибка badger"},
logger: (*service.LoggerService)(log),
}
return &r, nil
}
// Регистрация структур в кеше
func (c *CacheRepository) RegisterStruct(value interface{}) {
gob.Register(value)
}
func (k *CacheRepository) RunGC(ctx context.Context, interval time.Duration, discardRatio float64) {
go func() {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
start := time.Now()
for {
err := k.cache.RunValueLogGC(discardRatio)
if err != nil {
if err == badger.ErrNoRewrite {
break
}
k.logger.Error(service.LogErrorStruct{Message: "garbage collection failed: " + err.Error()})
break
}
}
k.logger.Log.Printf("garbage collection finished %v\n", time.Since(start))
case <-ctx.Done():
return
}
}
}()
}