mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-08-21 16:22:36 +08:00
fix: kill rclone subprocess on reader close
Prevent cat processes from hanging after the pipe is closed.
This commit is contained in:
@@ -8,7 +8,4 @@ var (
|
|||||||
ErrFailedToSaveFile = errors.New("rclone: failed to save file")
|
ErrFailedToSaveFile = errors.New("rclone: failed to save file")
|
||||||
ErrFailedToListFiles = errors.New("rclone: failed to list files")
|
ErrFailedToListFiles = errors.New("rclone: failed to list files")
|
||||||
ErrFailedToOpenFile = errors.New("rclone: failed to open file")
|
ErrFailedToOpenFile = errors.New("rclone: failed to open file")
|
||||||
ErrFailedToCheckFile = errors.New("rclone: failed to check file exists")
|
|
||||||
ErrFailedToCreateDir = errors.New("rclone: failed to create directory")
|
|
||||||
ErrCommandFailed = errors.New("rclone: command execution failed")
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/charmbracelet/log"
|
"github.com/charmbracelet/log"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/utils/fsutil"
|
||||||
config "github.com/krau/SaveAny-Bot/config/storage"
|
config "github.com/krau/SaveAny-Bot/config/storage"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/enums/ctxkey"
|
"github.com/krau/SaveAny-Bot/pkg/enums/ctxkey"
|
||||||
storenum "github.com/krau/SaveAny-Bot/pkg/enums/storage"
|
storenum "github.com/krau/SaveAny-Bot/pkg/enums/storage"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/storagetypes"
|
"github.com/krau/SaveAny-Bot/pkg/storagetypes"
|
||||||
"github.com/rs/xid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Rclone struct {
|
type Rclone struct {
|
||||||
@@ -51,9 +51,6 @@ func (r *Rclone) Init(ctx context.Context, cfg config.StorageConfig) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
remoteName := strings.TrimSuffix(r.config.Remote, ":")
|
remoteName := strings.TrimSuffix(r.config.Remote, ":")
|
||||||
if !strings.HasSuffix(r.config.Remote, ":") {
|
|
||||||
remoteName = r.config.Remote
|
|
||||||
}
|
|
||||||
|
|
||||||
found := false
|
found := false
|
||||||
scanner := bufio.NewScanner(bytes.NewReader(output))
|
scanner := bufio.NewScanner(bytes.NewReader(output))
|
||||||
@@ -105,18 +102,11 @@ func (r *Rclone) getRemotePath(storagePath string) string {
|
|||||||
func (r *Rclone) Save(ctx context.Context, reader io.Reader, storagePath string) error {
|
func (r *Rclone) Save(ctx context.Context, reader io.Reader, storagePath string) error {
|
||||||
r.logger.Infof("Saving file to %s", storagePath)
|
r.logger.Infof("Saving file to %s", storagePath)
|
||||||
|
|
||||||
ext := path.Ext(storagePath)
|
|
||||||
base := strings.TrimSuffix(storagePath, ext)
|
|
||||||
candidate := storagePath
|
candidate := storagePath
|
||||||
if overwrite, _ := ctx.Value(ctxkey.OverwriteExisting).(bool); !overwrite {
|
if overwrite, _ := ctx.Value(ctxkey.OverwriteExisting).(bool); !overwrite {
|
||||||
for i := 1; r.Exists(ctx, candidate); i++ {
|
candidate = fsutil.UniquePath("", storagePath, func(c string) bool {
|
||||||
candidate = fmt.Sprintf("%s_%d%s", base, i, ext)
|
return r.Exists(ctx, c)
|
||||||
if i > 100 {
|
}, 100)
|
||||||
r.logger.Errorf("Too many attempts to find a unique filename for %s", storagePath)
|
|
||||||
candidate = fmt.Sprintf("%s_%s%s", base, xid.New().String(), ext)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remotePath := r.getRemotePath(candidate)
|
remotePath := r.getRemotePath(candidate)
|
||||||
@@ -285,6 +275,12 @@ func (r *rcloneCatReader) Close() error {
|
|||||||
if err := r.reader.Close(); err != nil {
|
if err := r.reader.Close(); err != nil {
|
||||||
r.logger.Warnf("Failed to close reader: %v", err)
|
r.logger.Warnf("Failed to close reader: %v", err)
|
||||||
}
|
}
|
||||||
|
// 主动杀掉子进程, 防止 rclone cat 在管道关闭后仍挂起导致 Wait 永久阻塞
|
||||||
|
if r.cmd.Process != nil {
|
||||||
|
if err := r.cmd.Process.Kill(); err != nil {
|
||||||
|
r.logger.Warnf("Failed to kill rclone cat process: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := r.cmd.Wait(); err != nil {
|
if err := r.cmd.Wait(); err != nil {
|
||||||
r.logger.Warnf("rclone cat process exited with error: %v", err)
|
r.logger.Warnf("rclone cat process exited with error: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user