2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-24 13:47:42 +00:00

split deleteFiles into UI and logic parts

This commit is contained in:
Michael Eischer 2024-01-20 15:40:09 +01:00
parent 25ac1549e7
commit bedff1ed6d
2 changed files with 56 additions and 42 deletions

View File

@ -3,9 +3,6 @@ package main
import ( import (
"context" "context"
"golang.org/x/sync/errgroup"
"github.com/restic/restic/internal/backend"
"github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/restic"
) )
@ -24,46 +21,21 @@ func DeleteFilesChecked(ctx context.Context, gopts GlobalOptions, repo restic.Re
// deleteFiles deletes the given fileList of fileType in parallel // deleteFiles deletes the given fileList of fileType in parallel
// if ignoreError=true, it will print a warning if there was an error, else it will abort. // if ignoreError=true, it will print a warning if there was an error, else it will abort.
func deleteFiles(ctx context.Context, gopts GlobalOptions, ignoreError bool, repo restic.Repository, fileList restic.IDSet, fileType restic.FileType) error { func deleteFiles(ctx context.Context, gopts GlobalOptions, ignoreError bool, repo restic.Repository, fileList restic.IDSet, fileType restic.FileType) error {
totalCount := len(fileList) bar := newProgressMax(!gopts.JSON && !gopts.Quiet, 0, "files deleted")
fileChan := make(chan restic.ID) defer bar.Done()
wg, ctx := errgroup.WithContext(ctx)
wg.Go(func() error { return restic.ParallelRemove(ctx, repo, fileList, fileType, func(id restic.ID, err error) error {
defer close(fileChan) if err != nil {
for id := range fileList { if !gopts.JSON {
select { Warnf("unable to remove %v/%v from the repository\n", fileType, id)
case fileChan <- id: }
case <-ctx.Done(): if !ignoreError {
return ctx.Err() return err
} }
} }
if !gopts.JSON && gopts.verbosity > 2 {
Verbosef("removed %v/%v\n", fileType, id)
}
return nil return nil
}) }, bar)
bar := newProgressMax(!gopts.JSON && !gopts.Quiet, uint64(totalCount), "files deleted")
defer bar.Done()
// deleting files is IO-bound
workerCount := repo.Connections()
for i := 0; i < int(workerCount); i++ {
wg.Go(func() error {
for id := range fileChan {
h := backend.Handle{Type: fileType, Name: id.String()}
err := repo.Backend().Remove(ctx, h)
if err != nil {
if !gopts.JSON {
Warnf("unable to remove %v from the repository\n", h)
}
if !ignoreError {
return err
}
}
if !gopts.JSON && gopts.verbosity > 2 {
Verbosef("removed %v\n", h)
}
bar.Add(1)
}
return nil
})
}
err := wg.Wait()
return err
} }

View File

@ -3,7 +3,9 @@ package restic
import ( import (
"context" "context"
"github.com/restic/restic/internal/backend"
"github.com/restic/restic/internal/debug" "github.com/restic/restic/internal/debug"
"github.com/restic/restic/internal/ui/progress"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
@ -50,3 +52,43 @@ func ParallelList(ctx context.Context, r Lister, t FileType, parallelism uint, f
return wg.Wait() return wg.Wait()
} }
// ParallelRemove deletes the given fileList of fileType in parallel
// if callback returns an error, then it will abort.
func ParallelRemove(ctx context.Context, repo Repository, fileList IDSet, fileType FileType, report func(id ID, err error) error, bar *progress.Counter) error {
fileChan := make(chan ID)
wg, ctx := errgroup.WithContext(ctx)
wg.Go(func() error {
defer close(fileChan)
for id := range fileList {
select {
case fileChan <- id:
case <-ctx.Done():
return ctx.Err()
}
}
return nil
})
bar.SetMax(uint64(len(fileList)))
// deleting files is IO-bound
workerCount := repo.Connections()
for i := 0; i < int(workerCount); i++ {
wg.Go(func() error {
for id := range fileChan {
h := backend.Handle{Type: fileType, Name: id.String()}
err := repo.Backend().Remove(ctx, h)
if report != nil {
err = report(id, err)
}
if err != nil {
return err
}
bar.Add(1)
}
return nil
})
}
return wg.Wait()
}