mirror of
https://github.com/gilbertchen/duplicacy
synced 2025-12-15 15:53:26 +00:00
Fix bugs in sftp retrying
* Fixed a bug caused by nil sftp client during retry * Simplify the rework logic in UploadFile * Change the number of tries from 6 to 8
This commit is contained in:
@@ -91,7 +91,7 @@ func CreateSFTPStorage(server string, port int, username string, storageDir stri
|
|||||||
storageDir: storageDir,
|
storageDir: storageDir,
|
||||||
minimumNesting: minimumNesting,
|
minimumNesting: minimumNesting,
|
||||||
numberOfThreads: threads,
|
numberOfThreads: threads,
|
||||||
numberOfTries: 6,
|
numberOfTries: 8,
|
||||||
serverAddress: serverAddress,
|
serverAddress: serverAddress,
|
||||||
sftpConfig: sftpConfig,
|
sftpConfig: sftpConfig,
|
||||||
}
|
}
|
||||||
@@ -129,22 +129,19 @@ func (storage *SFTPStorage) retry(f func () error) error {
|
|||||||
delay *= 2
|
delay *= 2
|
||||||
|
|
||||||
storage.clientLock.Lock()
|
storage.clientLock.Lock()
|
||||||
if storage.client != nil {
|
|
||||||
storage.client.Close()
|
|
||||||
storage.client = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
connection, err := ssh.Dial("tcp", storage.serverAddress, storage.sftpConfig)
|
connection, err := ssh.Dial("tcp", storage.serverAddress, storage.sftpConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
LOG_WARN("SFT_RECONNECT", "Failed to connect to %s: %v; retrying", storage.serverAddress, err)
|
||||||
storage.clientLock.Unlock()
|
storage.clientLock.Unlock()
|
||||||
return err
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := sftp.NewClient(connection)
|
client, err := sftp.NewClient(connection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
LOG_WARN("SFT_RECONNECT", "Failed to create a new SFTP client to %s: %v; retrying", storage.serverAddress, err)
|
||||||
connection.Close()
|
connection.Close()
|
||||||
storage.clientLock.Unlock()
|
storage.clientLock.Unlock()
|
||||||
return err
|
continue
|
||||||
}
|
}
|
||||||
storage.client = client
|
storage.client = client
|
||||||
storage.clientLock.Unlock()
|
storage.clientLock.Unlock()
|
||||||
@@ -275,36 +272,19 @@ func (storage *SFTPStorage) UploadFile(threadIndex int, filePath string, content
|
|||||||
fullPath := path.Join(storage.storageDir, filePath)
|
fullPath := path.Join(storage.storageDir, filePath)
|
||||||
|
|
||||||
dirs := strings.Split(filePath, "/")
|
dirs := strings.Split(filePath, "/")
|
||||||
if len(dirs) > 1 {
|
|
||||||
fullDir := path.Dir(fullPath)
|
fullDir := path.Dir(fullPath)
|
||||||
err = storage.retry(func() error {
|
return storage.retry(func() error {
|
||||||
|
|
||||||
|
if len(dirs) > 1 {
|
||||||
_, err := storage.getSFTPClient().Stat(fullDir)
|
_, err := storage.getSFTPClient().Stat(fullDir)
|
||||||
return err
|
if os.IsNotExist(err) {
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
// The error may be caused by a non-existent fullDir, or a broken connection. In either case,
|
|
||||||
// we just assume it is the former because there isn't a way to tell which is the case.
|
|
||||||
for i := range dirs[1 : len(dirs)-1] {
|
for i := range dirs[1 : len(dirs)-1] {
|
||||||
subDir := path.Join(storage.storageDir, path.Join(dirs[0:i+2]...))
|
subDir := path.Join(storage.storageDir, path.Join(dirs[0:i+2]...))
|
||||||
// We don't check the error; just keep going blindly but always store the last err
|
// We don't check the error; just keep going blindly
|
||||||
err = storage.getSFTPClient().Mkdir(subDir)
|
storage.getSFTPClient().Mkdir(subDir)
|
||||||
}
|
|
||||||
|
|
||||||
// If there is an error creating the dirs, we check fullDir one more time, because another thread
|
|
||||||
// may happen to create the same fullDir ahead of this thread
|
|
||||||
if err != nil {
|
|
||||||
err = storage.retry(func() error {
|
|
||||||
_, err := storage.getSFTPClient().Stat(fullDir)
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return storage.retry(func() error {
|
|
||||||
|
|
||||||
letters := "abcdefghijklmnopqrstuvwxyz"
|
letters := "abcdefghijklmnopqrstuvwxyz"
|
||||||
suffix := make([]byte, 8)
|
suffix := make([]byte, 8)
|
||||||
|
|||||||
Reference in New Issue
Block a user