feat: media duplicate purge, part 1 of 3: persisted purge settings and the purge API
This commit is contained in:
1 parent
161ddc0f7d
commit
e82d0ce254
25 files changed
+2459
-41
No files matched your search
@@ -0,0 +1,91 @@
|
||||
package useCases
|
||||
|
||||
import (
|
||||
"RenewCMS/internal/domain/article"
|
||||
"RenewCMS/internal/domain/image"
|
||||
"RenewCMS/internal/domain/purge"
|
||||
"log"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RunPurgeResult struct {
|
||||
GroupsTotal int
|
||||
GroupsPurged int
|
||||
Merged int
|
||||
ArticlesUpdated int
|
||||
FailedGroups int
|
||||
}
|
||||
|
||||
type RunPurgeUseCase struct {
|
||||
planner *purgePlanner
|
||||
merge *MergeMediaUseCase
|
||||
repository purge.Repository
|
||||
now func() time.Time
|
||||
logger *log.Logger
|
||||
guard sync.Mutex
|
||||
}
|
||||
|
||||
func NewRunPurgeUseCase(imageRepository image.Repository, articleRepository article.Repository, merge *MergeMediaUseCase, repository purge.Repository, now func() time.Time, logger *log.Logger) *RunPurgeUseCase {
|
||||
return &RunPurgeUseCase{
|
||||
planner: &purgePlanner{imageRepository, articleRepository},
|
||||
merge: merge,
|
||||
repository: repository,
|
||||
now: now,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *RunPurgeUseCase) Run(fingerprint *string) (RunPurgeResult, error) {
|
||||
if !u.guard.TryLock() {
|
||||
return RunPurgeResult{}, purge.ErrPurgeBusy
|
||||
}
|
||||
defer u.guard.Unlock()
|
||||
|
||||
plan, err := u.planner.plan()
|
||||
if err != nil {
|
||||
return RunPurgeResult{}, err
|
||||
}
|
||||
if fingerprint != nil && *fingerprint != plan.fingerprint {
|
||||
return RunPurgeResult{}, purge.ErrPurgeConflict
|
||||
}
|
||||
|
||||
result := u.mergeGroups(plan)
|
||||
if err := u.recordRun(result); err != nil {
|
||||
u.logger.Printf("purge: could not record the run result: %v", err)
|
||||
return RunPurgeResult{}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (u *RunPurgeUseCase) mergeGroups(plan purgePlan) RunPurgeResult {
|
||||
result := RunPurgeResult{GroupsTotal: len(plan.groups)}
|
||||
updated := map[uint32]bool{}
|
||||
for _, group := range plan.groups {
|
||||
merged, err := u.merge.Merge(group.kept.ID, slices.Clone(group.mergedIds))
|
||||
if err != nil {
|
||||
result.FailedGroups++
|
||||
continue
|
||||
}
|
||||
result.GroupsPurged++
|
||||
result.Merged += merged.Merged
|
||||
for _, id := range merged.UpdatedArticleIDs {
|
||||
updated[id] = true
|
||||
}
|
||||
}
|
||||
result.ArticlesUpdated = len(updated)
|
||||
return result
|
||||
}
|
||||
|
||||
func (u *RunPurgeUseCase) recordRun(result RunPurgeResult) error {
|
||||
settings, err := u.repository.Get()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
at := u.now().UTC()
|
||||
settings.LastPurgeAt = &at
|
||||
settings.LastPurgeMerged = result.Merged
|
||||
settings.LastPurgeArticlesUpdated = result.ArticlesUpdated
|
||||
return u.repository.Save(settings)
|
||||
}
|
||||
Reference in new issue
Block a user