Files
RenewCMS/internal/infrastructure/useCases/RunPurge.go
T

76 lines
2.0 KiB
Go

package useCases
import (
"RenewCMS/internal/domain/article"
"RenewCMS/internal/domain/image"
"RenewCMS/internal/domain/purge"
"log"
"slices"
"sync"
"time"
)
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) (purge.RunResult, error) {
if !u.guard.TryLock() {
return purge.RunResult{}, purge.ErrPurgeBusy
}
defer u.guard.Unlock()
plan, err := u.planner.plan()
if err != nil {
return purge.RunResult{}, err
}
if fingerprint != nil && *fingerprint != plan.fingerprint {
return purge.RunResult{}, 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 purge.RunResult{}, err
}
return result, nil
}
func (u *RunPurgeUseCase) mergeGroups(plan purgePlan) purge.RunResult {
result := purge.RunResult{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 purge.RunResult) error {
return u.repository.SaveLastRun(u.now().UTC(), result.Merged, result.ArticlesUpdated)
}