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 }