box: delete items in parallel in cleanup using --checkers threads #5545

This commit is contained in:
Nick Craig-Wood 2021-08-22 17:41:30 +01:00
parent e18ae5da09
commit 34140b2f57

View File

@ -22,6 +22,8 @@ import (
"path" "path"
"strconv" "strconv"
"strings" "strings"
"sync"
"sync/atomic"
"time" "time"
"github.com/rclone/rclone/lib/encoder" "github.com/rclone/rclone/lib/encoder"
@ -1100,19 +1102,32 @@ func (f *Fs) deletePermanently(ctx context.Context, itemType, id string) error {
// CleanUp empties the trash // CleanUp empties the trash
func (f *Fs) CleanUp(ctx context.Context) (err error) { func (f *Fs) CleanUp(ctx context.Context) (err error) {
var deleteErrors = 0 var (
deleteErrors = int64(0)
concurrencyControl = make(chan struct{}, fs.GetConfig(ctx).Checkers)
wg sync.WaitGroup
)
_, err = f.listAll(ctx, "trash", false, false, false, func(item *api.Item) bool { _, err = f.listAll(ctx, "trash", false, false, false, func(item *api.Item) bool {
if item.Type == api.ItemTypeFolder || item.Type == api.ItemTypeFile { if item.Type == api.ItemTypeFolder || item.Type == api.ItemTypeFile {
err := f.deletePermanently(ctx, item.Type, item.ID) wg.Add(1)
if err != nil { concurrencyControl <- struct{}{}
fs.Errorf(f, "failed to delete trash item %q: %v", item.ID, err) go func() {
deleteErrors++ defer func() {
} <-concurrencyControl
wg.Done()
}()
err := f.deletePermanently(ctx, item.Type, item.ID)
if err != nil {
fs.Errorf(f, "failed to delete trash item %q (%q): %v", item.Name, item.ID, err)
atomic.AddInt64(&deleteErrors, 1)
}
}()
} else { } else {
fs.Debugf(f, "Ignoring %q - unknown type %q", item.Name, item.Type) fs.Debugf(f, "Ignoring %q - unknown type %q", item.Name, item.Type)
} }
return false return false
}) })
wg.Wait()
if deleteErrors != 0 { if deleteErrors != 0 {
return errors.Errorf("failed to delete %d trash items", deleteErrors) return errors.Errorf("failed to delete %d trash items", deleteErrors)
} }