feat: cancel copy for upload
This commit is contained in:
parent
935416de45
commit
ee2bc99e4c
@ -3,7 +3,6 @@ package local
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -144,8 +143,11 @@ func (d *Driver) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
|
|||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = out.Close()
|
_ = out.Close()
|
||||||
|
if errors.Is(err, context.Canceled) {
|
||||||
|
_ = os.Remove(fullPath)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
_, err = io.Copy(out, stream)
|
err = utils.CopyWithCtx(ctx, out, stream)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error while copy file %s", fullPath)
|
return errors.Wrapf(err, "error while copy file %s", fullPath)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import "context"
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
func IsCanceled(ctx context.Context) bool {
|
func IsCanceled(ctx context.Context) bool {
|
||||||
select {
|
select {
|
||||||
|
35
pkg/utils/io.go
Normal file
35
pkg/utils/io.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// here is some syntaxic sugar inspired by the Tomas Senart's video,
|
||||||
|
// it allows me to inline the Reader interface
|
||||||
|
type readerFunc func(p []byte) (n int, err error)
|
||||||
|
|
||||||
|
func (rf readerFunc) Read(p []byte) (n int, err error) { return rf(p) }
|
||||||
|
|
||||||
|
// CopyWithCtx slightly modified function signature:
|
||||||
|
// - context has been added in order to propagate cancelation
|
||||||
|
// - I do not return the number of bytes written, has it is not useful in my use case
|
||||||
|
func CopyWithCtx(ctx context.Context, out io.Writer, in io.Reader) error {
|
||||||
|
// Copy will call the Reader and Writer interface multiple time, in order
|
||||||
|
// to copy by chunk (avoiding loading the whole file in memory).
|
||||||
|
// I insert the ability to cancel before read time as it is the earliest
|
||||||
|
// possible in the call process.
|
||||||
|
_, err := io.Copy(out, readerFunc(func(p []byte) (int, error) {
|
||||||
|
// golang non-blocking channel: https://gobyexample.com/non-blocking-channel-operations
|
||||||
|
select {
|
||||||
|
// if context has been canceled
|
||||||
|
case <-ctx.Done():
|
||||||
|
// stop process and propagate "context canceled" error
|
||||||
|
return 0, ctx.Err()
|
||||||
|
default:
|
||||||
|
// otherwise just run default io.Reader implementation
|
||||||
|
return in.Read(p)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return err
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user