70 lines
1.5 KiB
Go
70 lines
1.5 KiB
Go
package worker
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"syscall"
|
|
|
|
"github.com/TopherMayor/unified-media-manager/internal/config"
|
|
"github.com/TopherMayor/unified-media-manager/internal/db"
|
|
)
|
|
|
|
type DiskUsageWorker struct {
|
|
database *db.DB
|
|
cfg *config.Config
|
|
}
|
|
|
|
func NewDiskUsageWorker(database *db.DB, cfg *config.Config) *DiskUsageWorker {
|
|
return &DiskUsageWorker{
|
|
database: database,
|
|
cfg: cfg,
|
|
}
|
|
}
|
|
|
|
func (w *DiskUsageWorker) Name() string {
|
|
return "disk_usage"
|
|
}
|
|
|
|
func (w *DiskUsageWorker) CronExpr() string {
|
|
return w.cfg.WorkerDiskUsageInterval
|
|
}
|
|
|
|
func (w *DiskUsageWorker) Run(ctx context.Context) error {
|
|
rows, err := w.database.Pool.Query(ctx, "SELECT id, path FROM root_folders")
|
|
if err != nil {
|
|
return fmt.Errorf("query root folders: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
updated := 0
|
|
for rows.Next() {
|
|
var id int64
|
|
var path string
|
|
if err := rows.Scan(&id, &path); err != nil {
|
|
slog.Error("failed to scan root folder", "error", err)
|
|
continue
|
|
}
|
|
|
|
var stat syscall.Statfs_t
|
|
if err := syscall.Statfs(path, &stat); err != nil {
|
|
slog.Error("failed to stat filesystem", "path", path, "error", err)
|
|
continue
|
|
}
|
|
|
|
freeSpace := int64(stat.Bavail) * int64(stat.Bsize)
|
|
|
|
_, err := w.database.Pool.Exec(ctx,
|
|
"UPDATE root_folders SET free_space = $1 WHERE id = $2",
|
|
freeSpace, id)
|
|
if err != nil {
|
|
slog.Error("failed to update free space", "id", id, "error", err)
|
|
continue
|
|
}
|
|
updated++
|
|
}
|
|
|
|
slog.Info("disk usage updated", "folders_updated", updated)
|
|
return nil
|
|
}
|