Fixed: File imports on cloud drives slow due to transaction logic
This commit is contained in:
parent
e28b2e8328
commit
95d64208d0
|
@ -20,15 +20,37 @@ namespace NzbDrone.Common.Test.DiskTests
|
|||
private readonly string _tempTargetPath = @"C:\target\my.video.mkv.partial~".AsOsAgnostic();
|
||||
private readonly string _nfsFile = ".nfs01231232";
|
||||
|
||||
private MockMount _sourceMount;
|
||||
private MockMount _targetMount;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>(MockBehavior.Strict);
|
||||
|
||||
_sourceMount = new MockMount()
|
||||
{
|
||||
Name = "source",
|
||||
RootDirectory = @"C:\source".AsOsAgnostic()
|
||||
};
|
||||
_targetMount = new MockMount()
|
||||
{
|
||||
Name = "target",
|
||||
RootDirectory = @"C:\target".AsOsAgnostic()
|
||||
};
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetMount(It.IsAny<string>()))
|
||||
.Returns((IMount)null);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetMount(It.Is<string>(p => p.StartsWith(_sourceMount.RootDirectory))))
|
||||
.Returns(_sourceMount);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetMount(It.Is<string>(p => p.StartsWith(_targetMount.RootDirectory))))
|
||||
.Returns(_targetMount);
|
||||
|
||||
WithEmulatedDiskProvider();
|
||||
|
||||
WithExistingFile(_sourcePath);
|
||||
|
@ -58,6 +80,27 @@ namespace NzbDrone.Common.Test.DiskTests
|
|||
.Verify(v => v.MoveFile(_sourcePath, _targetPath, false), Times.Once());
|
||||
}
|
||||
|
||||
[TestCase("fuse.mergerfs")]
|
||||
[TestCase("fuse.rclone")]
|
||||
[TestCase("mergerfs")]
|
||||
[TestCase("rclone")]
|
||||
public void should_not_use_verified_transfer_on_specific_filesystems(string fs)
|
||||
{
|
||||
MonoOnly();
|
||||
|
||||
_targetMount.DriveFormat = fs;
|
||||
|
||||
Subject.VerificationMode.Should().Be(DiskTransferVerificationMode.VerifyOnly);
|
||||
|
||||
var result = Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.TryCreateHardLink(_sourcePath, _backupPath), Times.Never());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.MoveFile(_sourcePath, _targetPath, false), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_path_is_the_same()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
using System.IO;
|
||||
using NzbDrone.Common.Disk;
|
||||
|
||||
namespace NzbDrone.Common.Test.DiskTests
|
||||
{
|
||||
public class MockMount : IMount
|
||||
{
|
||||
public long AvailableFreeSpace { get; set; }
|
||||
|
||||
public string DriveFormat { get; set; }
|
||||
|
||||
public DriveType DriveType { get; set; } = DriveType.Fixed;
|
||||
|
||||
public bool IsReady { get; set; } = true;
|
||||
|
||||
public MountOptions MountOptions { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string RootDirectory { get; set; }
|
||||
|
||||
public long TotalFreeSpace { get; set; }
|
||||
|
||||
public long TotalSize { get; set; }
|
||||
|
||||
public string VolumeLabel { get; set; }
|
||||
|
||||
public string VolumeName { get; set; }
|
||||
}
|
||||
}
|
|
@ -288,15 +288,31 @@ namespace NzbDrone.Common.Disk
|
|||
}
|
||||
}
|
||||
|
||||
// We force a transactional transfer if the transfer occurs between mounts and one of the mounts is cifs, it would be a copy anyway.
|
||||
if (verificationMode == DiskTransferVerificationMode.TryTransactional && OsInfo.IsNotWindows)
|
||||
// Adjust the transfer mode depending on the filesystems
|
||||
if (verificationMode == DiskTransferVerificationMode.TryTransactional)
|
||||
{
|
||||
var sourceMount = _diskProvider.GetMount(sourcePath);
|
||||
var targetMount = _diskProvider.GetMount(targetPath);
|
||||
|
||||
if (sourceMount != null && targetMount != null && sourceMount.RootDirectory != targetMount.RootDirectory &&
|
||||
(sourceMount.DriveFormat == "cifs" || targetMount.DriveFormat == "cifs"))
|
||||
var isSameMount = (sourceMount != null && targetMount != null && sourceMount.RootDirectory == targetMount.RootDirectory);
|
||||
|
||||
var sourceDriveFormat = sourceMount?.DriveFormat ?? string.Empty;
|
||||
var targetDriveFormat = targetMount?.DriveFormat ?? string.Empty;
|
||||
|
||||
if (isSameMount)
|
||||
{
|
||||
// No transaction needed for operations on same mount, force VerifyOnly
|
||||
verificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||
}
|
||||
else if (sourceDriveFormat.Contains("mergerfs") || sourceDriveFormat.Contains("rclone") ||
|
||||
targetDriveFormat.Contains("mergerfs") || targetDriveFormat.Contains("rclone"))
|
||||
{
|
||||
// Cloud storage filesystems don't need any Transactional stuff and it hurts performance, force VerifyOnly
|
||||
verificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||
}
|
||||
else if ((sourceDriveFormat == "cifs" || targetDriveFormat == "cifs") && OsInfo.IsNotWindows)
|
||||
{
|
||||
// Force Transactional on a cifs mount due to the likeliness of move failures on certain scenario's on mono
|
||||
verificationMode = DiskTransferVerificationMode.Transactional;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue