From ab0587bd4d0523764cd2cc3c447a10d42bc9e0bf Mon Sep 17 00:00:00 2001 From: keven1024 Date: Mon, 25 May 2026 13:43:30 +0800 Subject: [PATCH] feat(tasks): add file janitor task for cleaning up unused files and schedule it --- worker/internal/tasks/file.go | 60 +++++++++++++++++++++++++++++++++++ worker/main.go | 10 ++++++ 2 files changed, 70 insertions(+) diff --git a/worker/internal/tasks/file.go b/worker/internal/tasks/file.go index b43f365..cdd1a05 100644 --- a/worker/internal/tasks/file.go +++ b/worker/internal/tasks/file.go @@ -55,3 +55,63 @@ func RemoveFile(ctx context.Context, task *asynq.Task) error { } return nil } + +func FileJanitor(_ context.Context, _ *asynq.Task) error { + uploadPath, err := u.GetUploadDirPath() + if err != nil { + return err + } + + entries, err := os.ReadDir(uploadPath) + if err != nil { + return err + } + + allFileInfo, err := models.GetRedisFileInfoAll() + if err != nil { + return err + } + + // Case 1: 本地有但 fileInfoMap 無 → 直接刪除 + for _, entry := range entries { + name := entry.Name() + fileId := strings.TrimSuffix(name, "_tmp") + if _, exists := allFileInfo[fileId]; !exists { + if err := os.RemoveAll(filepath.Join(uploadPath, name)); err != nil { + return err + } + } + } + + // Case 2 & 3: 遍歷 fileInfoMap + now := time.Now().Unix() + for fileId, rawInfo := range allFileInfo { + var info models.RedisFileInfo + if err := json.Unmarshal([]byte(rawInfo), &info); err != nil { + continue + } + + // Case 2: init 狀態且已過期 + if info.FileType == models.FileTypeInit && info.CreatedAt+info.Expire < now { + if err := pkgservices.SetFileRemoveTask(fileId, 0); err != nil { + return err + } + continue + } + + // Case 3: 已完成上傳但無 share 關係 + if info.FileType == models.FileTypeUpload { + shareIDs, err := models.GetRedisFileShareRelational(fileId) + if err != nil { + return err + } + if len(shareIDs) == 0 { + if err := pkgservices.SetFileRemoveTask(fileId, 0); err != nil { + return err + } + } + } + } + + return nil +} diff --git a/worker/main.go b/worker/main.go index a31ede5..f3026a6 100644 --- a/worker/main.go +++ b/worker/main.go @@ -46,10 +46,20 @@ func main() { mux.HandleFunc("share:remove", tasks.RemoveShare) mux.HandleFunc("share:notify", tasks.ShareNotify) mux.HandleFunc("file:remove", tasks.RemoveFile) + mux.HandleFunc("file:janitor", tasks.FileJanitor) mux.HandleFunc("image:compress", tasks.CompressImage) mux.HandleFunc("image:convert", tasks.ConvertImage) mux.HandleFunc("text:translate", tasks.TranslateText) + scheduler := asynq.NewScheduler(utils.RedisURI2AsynqOpt(utils.GetEnv("redis.url")), nil) + if _, err := scheduler.Register("0 3 * * *", asynq.NewTask("file:janitor", nil)); err != nil { + log.Fatalf("could not register scheduler: %v", err) + } + if err := scheduler.Start(); err != nil { + log.Fatalf("could not start scheduler: %v", err) + } + defer scheduler.Shutdown() + if err := srv.Run(mux); err != nil { log.Fatalf("could not run server: %v", err) }