Files
safebin/internal/app/storage.go
T
x aca7267301 refactor: internals
Signed-off-by: skidoodle <contact@albert.lol>
2026-01-17 22:58:38 +01:00

90 lines
1.9 KiB
Go

package app
import (
"context"
"math"
"os"
"path/filepath"
"time"
)
const (
cleanupInterval = 1 * time.Hour
tempExpiry = 4 * time.Hour
minRetention = 24 * time.Hour
maxRetention = 365 * 24 * time.Hour
bytesInMB = 1 << 20
)
func (app *App) StartCleanupTask(ctx context.Context) {
ticker := time.NewTicker(cleanupInterval)
for {
select {
case <-ctx.Done():
ticker.Stop()
return
case <-ticker.C:
app.CleanStorage(app.Conf.StorageDir)
app.CleanTemp(filepath.Join(app.Conf.StorageDir, "tmp"))
}
}
}
func (app *App) CleanStorage(path string) {
entries, err := os.ReadDir(path)
if err != nil {
app.Logger.Error("Failed to read storage dir", "err", err)
return
}
for _, entry := range entries {
info, err := entry.Info()
if err != nil {
continue
}
expiry := CalculateRetention(info.Size(), app.Conf.MaxMB)
if time.Since(info.ModTime()) > expiry {
if err := os.RemoveAll(filepath.Join(path, entry.Name())); err != nil {
app.Logger.Error("Failed to remove expired file", "path", entry.Name(), "err", err)
}
}
}
}
func (app *App) CleanTemp(path string) {
entries, err := os.ReadDir(path)
if err != nil {
app.Logger.Error("Failed to read temp dir", "err", err)
return
}
for _, entry := range entries {
info, err := entry.Info()
if err != nil {
continue
}
if time.Since(info.ModTime()) > tempExpiry {
if err := os.RemoveAll(filepath.Join(path, entry.Name())); err != nil {
app.Logger.Error("Failed to remove expired temp file", "path", entry.Name(), "err", err)
}
}
}
}
func CalculateRetention(fileSize, maxMB int64) time.Duration {
ratio := math.Max(0, math.Min(1, float64(fileSize)/float64(maxMB*bytesInMB)))
invRatio := 1.0 - ratio
retention := float64(maxRetention) * (invRatio * invRatio * invRatio)
if retention < float64(minRetention) {
return minRetention
}
return time.Duration(retention)
}