Eric Bower
·
2026-03-05
cron_bin.go
1package pgs
2
3import (
4 "log/slog"
5 "time"
6
7 pgsdb "github.com/picosh/pico/pkg/apps/pgs/db"
8 "github.com/picosh/pico/pkg/shared"
9 "github.com/picosh/pico/pkg/shared/storage"
10)
11
12const binRetentionDays = 14
13
14func BinCron(cfg *PgsConfig) {
15 logger := cfg.Logger
16 storage := cfg.Storage
17 db := cfg.DB
18
19 // Loop every 10 minutes
20 ticker := time.NewTicker(10 * time.Minute)
21 defer ticker.Stop()
22 deleteOldBinObjects(logger, db, storage)
23
24 for range ticker.C {
25 deleteOldBinObjects(logger, db, storage)
26 }
27}
28
29func deleteOldBinObjects(logger *slog.Logger, db pgsdb.PgsDB, storage storage.StorageServe) {
30 logger.Info("running bin cron")
31 users, err := db.FindUsers()
32 if err != nil {
33 logger.Error("failed to find users", "error", err)
34 return
35 }
36
37 for _, user := range users {
38 log := shared.LoggerWithUser(logger, user)
39 bucketName := shared.GetAssetBucketName(user.ID)
40 bucket, err := storage.GetBucket(bucketName)
41 if err != nil {
42 log.Error("failed to get bucket", "bucket", bucketName, "error", err)
43 continue
44 }
45
46 project, err := db.FindProjectByName(user.ID, "bin")
47 if err != nil {
48 continue
49 }
50
51 log = log.With("project", project.Name)
52
53 objs, err := storage.ListObjects(bucket, project.ProjectDir+"/", true)
54 if err != nil {
55 log.Error("failed to list objects", "error", err)
56 continue
57 }
58
59 cutoff := time.Now().Add(-binRetentionDays * 24 * time.Hour)
60 for _, obj := range objs {
61 if obj.IsDir() {
62 continue
63 }
64
65 if obj.ModTime().Before(cutoff) {
66 objPath := project.ProjectDir + "/" + obj.Name()
67 if err := storage.DeleteObject(bucket, objPath); err != nil {
68 logger.Error("failed to delete old object", "file", obj.Name(), "error", err)
69 } else {
70 logger.Info("deleted old object", "file", obj.Name(), "age", time.Since(obj.ModTime()))
71 }
72 }
73 }
74 }
75}